X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-transport-wlan-helper.c;h=25e55e510a583ca3287aa457608a10addb84f999;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=f481a0fb6aa16b7dc40464822262708ba42b4faa;hpb=9df3d510bfb933e77347d214f24a1471c5df880f;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index f481a0fb6..25e55e510 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 2011 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -28,9 +28,15 @@ * gnunet */ +/** + * parts taken from aircrack-ng, parts changend. + */ + +#define _GNU_SOURCE #include #include #include +#include #include #include #include @@ -44,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +60,6 @@ //#include #include #include - //#include #include */ //#include "platform.h" @@ -69,11 +73,6 @@ #include "gnunet-transport-wlan-helper.h" #include "gnunet_crypto_lib.h" -#include -#include -#include -#include - #include "wlan/radiotap-parser.h" /* radiotap-parser defines types like u8 that * ieee80211_radiotap.h needs @@ -85,194 +84,81 @@ */ #include "wlan/ieee80211_radiotap.h" #include "wlan/crctable_osdep.h" -#include "wlan/loopback_helper.h" +//#include "wlan/loopback_helper.h" +//#include "wlan/ieee80211.h" +#include "wlan/helper_common.h" #define ARPHRD_IEEE80211 801 #define ARPHRD_IEEE80211_PRISM 802 #define ARPHRD_IEEE80211_FULL 803 -int first; -int closeprog; - -#include "wlan/helper_common.h" -#include "wlan/loopback_helper.h" - #define DEBUG 1 -typedef enum -{ - DT_NULL = 0, - DT_WLANNG, - DT_HOSTAP, - DT_MADWIFI, - DT_MADWIFING, - DT_BCM43XX, - DT_ORINOCO, - DT_ZD1211RW, - DT_ACX, - DT_MAC80211_RT, - DT_AT76USB, - DT_IPW2200 - -} DRIVER_TYPE; - -static const char * szaDriverTypes[] = - { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP", - [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG", - [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco", - [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX", - [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb", - [DT_IPW2200] = "ipw2200" }; - -struct Hardware_Infos -{ - - struct sendbuf *write_pout; - int fd_in, arptype_in; - int fd_out, arptype_out; - int fd_main; - int fd_rtc; - - DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */ - - FILE *f_cap_in; - - struct pcap_file_header pfh_in; - - int sysfs_inject; - int channel; - int freq; - int rate; - int tx_power; - char *wlanctlng; /* XXX never set */ - char *iwpriv; - char *iwconfig; - char *ifconfig; - char *iface; - char *main_if; - unsigned char pl_mac[6]; - int inject_wlanng; -}; - -//#include "radiotap.h" - -// mac of this node -char mac[] = - { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 }; +#define MAC_ADDR_SIZE 6 -/* wifi bitrate to use in 500kHz units */ -static const u8 u8aRatesToUse[] = - { - - 54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5 - 2 * 2, 1 * 2 }; - -#define OFFSET_FLAGS 0x10 -#define OFFSET_RATE 0x11 - -// this is where we store a summary of the -// information from the radiotap header +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ -typedef struct -{ - int m_nChannel; - int m_nChannelFlags; - int m_nRate; - int m_nAntenna; - int m_nRadiotapFlags; -}__attribute__((packed)) PENUMBRA_RADIOTAP_DATA; - -static void -sigfunc_hw(int sig) +/* + * generic definitions for IEEE 802.11 frames + */ +struct ieee80211_frame { - closeprog = 1; -} + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} GNUNET_PACKED; -void -Dump(u8 * pu8, int nLength) +/** + * struct for storing the information of the hardware + */ +struct Hardware_Infos { - char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1; - unsigned char baaLast[2][16]; - uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0; - buf = szBuf; - szChar[0] = '\0'; + /** + * send buffer + */ + struct sendbuf write_pout; + /** + * file descriptor for the raw socket + */ + int fd_raw; - for (n = 0; n < nLength; n++) - { - baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n]; - if ((pu8[n] < 32) || (pu8[n] >= 0x7f)) - szChar[n & 0xf] = '.'; - else - szChar[n & 0xf] = pu8[n]; - szChar[(n & 0xf) + 1] = '\0'; - nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]); - if ((n & 15) != 15) - continue; - if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) - { - nSameCount++; - } - else - { - if (nSameCount) - buf += sprintf(buf, "(repeated %d times)\n", nSameCount); - buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar); - nSameCount = 0; - printf("%s", szBuf); - buf = szBuf; - } - nPos = 0; - nStart = n + 1; - nLine++; - fFirst = 0; - sz[0] = '\0'; - szChar[0] = '\0'; - } - if (nSameCount) - buf += sprintf(buf, "(repeated %d times)\n", nSameCount); + int arptype_in; - buf += sprintf(buf, "%04x: %s", nStart, sz); - if (n & 0xf) - { - *buf++ = ' '; - while (n & 0xf) - { - buf += sprintf(buf, " "); - n++; - } - } - buf += sprintf(buf, "%s\n", szChar); - printf("%s", szBuf); -} + /** + * Name of the interface, not necessarily 0-terminated (!). + */ + char iface[IFNAMSIZ]; + unsigned char pl_mac[MAC_ADDR_SIZE]; +}; -void -usage() +struct RadioTapheader { - printf("Usage: wlan-hwd [options] \n\nOptions\n" - "-f/--fcs Mark as having FCS (CRC) already\n" - " (pkt ends with 4 x sacrificial - chars)\n" - "Example:\n" - " echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n" - " iwconfig mon0 mode monitor\n" - " ifconfig mon0 up\n" - " wlan-hwd mon0 Spam down mon0 with\n" - " radiotap header first\n" - "\n"); - exit(1); -} + struct ieee80211_radiotap_header header; + u8 rate; + u8 pad1; + u16 txflags; +}; -void -packet_callback(unsigned char *Args, const struct pcap_pkthdr* Pkthdr, - unsigned char *Packet) -{ - fprintf(stderr, "+"); - fflush(stderr); -} +// FIXME: inline? +int +getChannelFromFrequency (int frequency); -unsigned long -calc_crc_osdep(unsigned char * buf, int len) +// FIXME: make nice... +/** + * function to calculate the crc, the start of the calculation + * @param buf buffer to calc the crc + * @param len len of the buffer + * @return crc sum + */ +static unsigned long +calc_crc_osdep (unsigned char *buf, int len) { unsigned long crc = 0xFFFFFFFF; @@ -284,376 +170,263 @@ calc_crc_osdep(unsigned char * buf, int len) /* CRC checksum verification routine */ -int -check_crc_buf_osdep(unsigned char *buf, int len) +// FIXME: make nice... +/** + * Function to check crc of the wlan packet + * @param buf buffer of the packet + * @param len len of the data + * @return crc sum of the data + */ +static int +check_crc_buf_osdep (unsigned char *buf, int len) { unsigned long crc; - if (len < 0) + if (0 > len) return 0; - crc = calc_crc_osdep(buf, len); + crc = calc_crc_osdep (buf, len); buf += len; - return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc - >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); -} - -/* Search a file recursively */ -static char * -searchInside(const char * dir, const char * filename) -{ - char * ret; - char * curfile; - struct stat sb; - int len, lentot; - DIR *dp; - struct dirent *ep; - - dp = opendir(dir); - if (dp == NULL) - { - return NULL; - } - - len = strlen(filename); - lentot = strlen(dir) + 256 + 2; - curfile = (char *) calloc(1, lentot); - - while ((ep = readdir(dp)) != NULL) - { - - memset(curfile, 0, lentot); - sprintf(curfile, "%s/%s", dir, ep->d_name); - - //Checking if it's the good file - if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename)) - { - (void) closedir(dp); - return curfile; - } - lstat(curfile, &sb); - - //If it's a directory and not a link, try to go inside to search - if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) - { - //Check if the directory isn't "." or ".." - if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name)) - { - //Recursive call - ret = searchInside(curfile, filename); - if (ret != NULL) - { - (void) closedir(dp); - free(curfile); - return ret; - } - } - } - } - (void) closedir(dp); - free(curfile); - return NULL; + return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && + ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); } -/* Search a wireless tool and return its path */ -static char * -wiToolsPath(const char * tool) -{ - char * path; - int i, nbelems; - static const char * paths[] = - { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin", - "/usr/local/bin", "/tmp" }; - - nbelems = sizeof(paths) / sizeof(char *); - - for (i = 0; i < nbelems; i++) - { - path = searchInside(paths[i], tool); - if (path != NULL) - return path; - } - - return NULL; -} +// FIXME: make nice... +/** + * function to get the channel of a specific wlan card + * @param dev pointer to the dev struct of the card + * @return channel number + */ static int -linux_get_channel(struct Hardware_Infos *dev) +linux_get_channel (struct Hardware_Infos *dev) { struct iwreq wrq; int fd, frequency; int chan = 0; - memset(&wrq, 0, sizeof(struct iwreq)); - - if (dev->main_if) - strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ ); - else - strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ ); + memset (&wrq, 0, sizeof (struct iwreq)); - fd = dev->fd_in; - if (dev->drivertype == DT_IPW2200) - fd = dev->fd_main; + strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); - if (ioctl(fd, SIOCGIWFREQ, &wrq) < 0) + fd = dev->fd_raw; + if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) return (-1); frequency = wrq.u.freq.m; - if (frequency > 100000000) + if (100000000 < frequency) frequency /= 100000; - else if (frequency > 1000000) + else if (1000000 < frequency) frequency /= 1000; - if (frequency > 1000) - chan = getChannelFromFrequency(frequency); + if (1000 < frequency) + chan = getChannelFromFrequency (frequency); else chan = frequency; return chan; } -static int -linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, - struct rx_info * ri) -{ - unsigned char tmpbuf[4096]; - int caplen, n, got_signal, got_noise, got_channel, fcs_removed; +// FIXME: make nice... +/** + * function to read from a wlan card + * @param dev pointer to the struct of the wlan card + * @param buf buffer to read to + * @param buf_size size of the buffer + * @param ri radiotap_rx info + * @return size read from the buffer + */ +static ssize_t +linux_read (struct Hardware_Infos *dev, unsigned char *buf, /* FIXME: void*? */ + size_t buf_size, struct Radiotap_rx *ri) +{ + unsigned char tmpbuf[buf_size]; + ssize_t caplen; + int n, got_signal, got_noise, got_channel, fcs_removed; - caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0; + n = got_signal = got_noise = got_channel = fcs_removed = 0; - if ((unsigned) count > sizeof(tmpbuf)) - return (-1); - caplen = read(dev->fd_in, tmpbuf, count); + caplen = read (dev->fd_raw, tmpbuf, buf_size); if (0 > caplen) - { - if (errno == EAGAIN) - return (0); - - perror("read failed"); - return (-1); - } - - memset(buf, 0, sizeof(buf)); + { + if (EAGAIN == errno) + return 0; + fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno)); + return -1; + } - /* XXX */ - if (ri) - memset(ri, 0, sizeof(*ri)); + memset (buf, 0, buf_size); + memset (ri, 0, sizeof (*ri)); - if (dev->arptype_in == ARPHRD_IEEE80211_PRISM) + switch (dev->arptype_in) + { + case ARPHRD_IEEE80211_PRISM: + { + /* skip the prism header */ + if (tmpbuf[7] == 0x40) { - /* skip the prism header */ - if (tmpbuf[7] == 0x40) - { - /* prism54 uses a different format */ - if (ri) - { - ri->ri_power = tmpbuf[0x33]; - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; - - got_signal = 1; - got_noise = 1; - } - - n = 0x40; - } - else - { - if (ri) - { - ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48); - ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); - ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; - - got_channel = 1; - got_signal = 1; - got_noise = 1; - } - - n = *(int *) (tmpbuf + 4); - } - - if (n < 8 || n >= caplen) - return (0); + /* prism54 uses a different format */ + ri->ri_power = tmpbuf[0x33]; + ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); + ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; + got_signal = 1; + got_noise = 1; + n = 0x40; } - - if (dev->arptype_in == ARPHRD_IEEE80211_FULL) + else { - struct ieee80211_radiotap_iterator iterator; - struct ieee80211_radiotap_header *rthdr; - - rthdr = (struct ieee80211_radiotap_header *) tmpbuf; - - if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0) - return (0); - - /* go through the radiotap arguments we have been given - * by the driver - */ + ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48); + ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); + ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); + ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); + ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; + got_channel = 1; + got_signal = 1; + got_noise = 1; + n = *(int *) (tmpbuf + 4); + } - while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0)) - { + if (n < 8 || n >= caplen) + return (0); + } + break; - switch (iterator.this_arg_index) - { - - case IEEE80211_RADIOTAP_TSFT: - ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg)); - break; - - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_ANTENNA: - ri->ri_antenna = *iterator.this_arg; - break; - - case IEEE80211_RADIOTAP_CHANNEL: - ri->ri_channel = *iterator.this_arg; - got_channel = 1; - break; - - case IEEE80211_RADIOTAP_RATE: - ri->ri_rate = (*iterator.this_arg) * 500000; - break; - - case IEEE80211_RADIOTAP_FLAGS: - /* is the CRC visible at the end? - * remove - */ - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) - { - fcs_removed = 1; - caplen -= 4; - } - - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) - return (0); - - break; - - } - } + case ARPHRD_IEEE80211_FULL: + { + struct ieee80211_radiotap_iterator iterator; + struct ieee80211_radiotap_header *rthdr; - n = le16_to_cpu(rthdr->it_len); + rthdr = (struct ieee80211_radiotap_header *) tmpbuf; - if (n <= 0 || n >= caplen) - return (0); - } + if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) + return (0); - caplen -= n; + /* go through the radiotap arguments we have been given + * by the driver + */ - //detect fcs at the end, even if the flag wasn't set and remove it - if (fcs_removed == 0 && check_crc_buf_osdep(tmpbuf + n, caplen - 4) == 1) + while (ieee80211_radiotap_iterator_next (&iterator) >= 0) { - caplen -= 4; - } - memcpy(buf, tmpbuf + n, caplen); + switch (iterator.this_arg_index) + { - if (ri && !got_channel) - ri->ri_channel = linux_get_channel(dev); + case IEEE80211_RADIOTAP_TSFT: + ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg)); + break; - return (caplen); -} + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + if (!got_signal) + { + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; -static int -linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count) -{ - int ret, usedrtap = 0; - unsigned short int *p_rtlen; + got_signal = 1; + } + break; - unsigned char * u8aRadiotap = buf; + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + if (!got_signal) + { + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; - /* Pointer to the radiotap header length field for later use. */ - p_rtlen = (unsigned short int*) (u8aRadiotap + 2); - usedrtap = 0; - ret = write(dev->fd_out, buf, count); + got_signal = 1; + } + break; - if (ret < 0) - { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno - == ENOMEM) + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + if (!got_noise) { - usleep(10000); - return (0); - } + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; - perror("write failed"); - return (-1); - } + got_noise = 1; + } + break; - /* radiotap header length is stored little endian on all systems */ - if (usedrtap) - ret -= letoh16(*p_rtlen); + case IEEE80211_RADIOTAP_DB_ANTNOISE: + if (!got_noise) + { + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; - if (ret < 0) - { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno - == ENOMEM) + got_noise = 1; + } + break; + + case IEEE80211_RADIOTAP_ANTENNA: + ri->ri_antenna = *iterator.this_arg; + break; + + case IEEE80211_RADIOTAP_CHANNEL: + ri->ri_channel = *iterator.this_arg; + got_channel = 1; + break; + + case IEEE80211_RADIOTAP_RATE: + ri->ri_rate = (*iterator.this_arg) * 500000; + break; + + case IEEE80211_RADIOTAP_FLAGS: + /* is the CRC visible at the end? + * remove + */ + if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { - usleep(10000); - return (0); + fcs_removed = 1; + caplen -= 4; } - perror("write failed"); - return (-1); + if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) + return (0); + + break; + } } + n = le16_to_cpu (rthdr->it_len); + if (n <= 0 || n >= caplen) + return 0; + } + break; + case ARPHRD_IEEE80211: + /* do nothing? */ + break; + default: + errno = ENOTSUP; + return -1; + } + + caplen -= n; + + //detect fcs at the end, even if the flag wasn't set and remove it + if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) + { + caplen -= 4; + } + memcpy (buf, tmpbuf + n, caplen); + if (!got_channel) + ri->ri_channel = linux_get_channel (dev); - return (ret); + return caplen; } +/** + * function to open the device for read/write + * @param dev pointer to the device struct + * @return 0 on success + */ static int -openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, - uint8_t *mac) +openraw (struct Hardware_Infos *dev) { struct ifreq ifr; struct iwreq wrq; @@ -661,806 +434,607 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, struct sockaddr_ll sll; /* find the interface index */ + memset (&ifr, 0, sizeof (ifr)); + strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ); + if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr)) + { + fprintf (stderr, + "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); - - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) - { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFINDEX) failed"); - return (1); - } - - memset(&sll, 0, sizeof(sll)); + /* lookup the hardware type */ + memset (&sll, 0, sizeof (sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; - - switch (dev->drivertype) - { - default: - sll.sll_protocol = htons(ETH_P_ALL); - break; - } - - /* lookup the hardware type */ - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) - { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFHWADDR) failed"); - return (1); - } + sll.sll_protocol = htons (ETH_P_ALL); + if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) + { + fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } /* lookup iw mode */ - memset(&wrq, 0, sizeof(struct iwreq)); - strncpy(wrq.ifr_name, iface, IFNAMSIZ); - - if (ioctl(fd, SIOCGIWMODE, &wrq) < 0) - { - /* most probably not supported (ie for rtap ipw interface) * - * so just assume its correctly set... */ - wrq.u.mode = IW_MODE_MONITOR; - } - - if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR)) - { - printf("Error: %s not in monitor mode\n", iface); - return (1); - } + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); + if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq)) + { + /* most probably not supported (ie for rtap ipw interface) * + * so just assume its correctly set... */ + wrq.u.mode = IW_MODE_MONITOR; + } + + if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || + (wrq.u.mode != IW_MODE_MONITOR)) + { + fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n", + IFNAMSIZ, dev->iface); + return 1; + } /* Is interface st to up, broadcast & running ? */ if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) - { - /* Bring interface up*/ - ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; - - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - { - perror("ioctl(SIOCSIFFLAGS) failed"); - return (1); - } - } - /* bind the raw socket to the interface */ - - if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0) - { - printf("Interface %s: \n", iface); - perror("bind(ETH_P_ALL) failed"); - return (1); - } - - /* lookup the hardware type */ + { + /* Bring interface up */ + ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) + if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFHWADDR) failed"); - return (1); + fprintf (stderr, + "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; } + } - memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6); - - *arptype = ifr.ifr_hwaddr.sa_family; + /* bind the raw socket to the interface */ + if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll))) + { + fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ, + dev->iface, strerror (errno)); + return 1; + } - if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_FULL) - { - if (ifr.ifr_hwaddr.sa_family == 1) - fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) "); - else - fprintf(stderr, "\nUnsupported hardware link type %4d ", - ifr.ifr_hwaddr.sa_family); - - fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_" - "FULL or ARPHRD_IEEE80211_PRISM instead. Make\n" - "sure RFMON is enabled: run 'airmon-ng start %s" - " <#>'\nSysfs injection support was not found " - "either.\n\n", iface); - return (1); - } + /* lookup the hardware type */ + if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) + { + fprintf (stderr, + "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } + + memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); + dev->arptype_in = ifr.ifr_hwaddr.sa_family; + if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) + { + fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n", + ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface); + return 1; + } /* enable promiscuous mode */ - - memset(&mr, 0, sizeof(mr)); + memset (&mr, 0, sizeof (mr)); mr.mr_ifindex = sll.sll_ifindex; mr.mr_type = PACKET_MR_PROMISC; + if (0 != + setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, + sizeof (mr))) + { + fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n", + IFNAMSIZ, dev->iface); + return 1; + } - if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) - { - perror("setsockopt(PACKET_MR_PROMISC) failed"); - return (1); - } - - return (0); + return 0; } -int -wlaninit(struct Hardware_Infos * dev, char *iface) +/** + * function to prepare the helper, e.g. sockets, device... + * @param dev struct for the device + * @param iface name of the interface + * @return 0 on success + */ +static int +wlaninit (struct Hardware_Infos *dev, const char *iface) { - - char *iwpriv; char strbuf[512]; - dev->inject_wlanng = 1; - dev->rate = 2; /* default to 1Mbps if nothing is set */ - - /* open raw socks */ - dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (0 > dev->fd_in) - { - perror("socket(PF_PACKET) failed at fd_in"); - if (getuid() != 0) - fprintf(stderr, "This program requires root privileges.\n"); - return (1); - } + struct stat sbuf; + int ret; - dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) ); - if (0 > dev->fd_main) - { - perror("socket(PF_PACKET) failed at fd_main"); - if (getuid() != 0) - fprintf(stderr, "This program requires root privileges.\n"); - return (1); - } - - /* Check iwpriv existence */ - - iwpriv = wiToolsPath("iwpriv"); - dev->iwpriv = iwpriv; - dev->iwconfig = wiToolsPath("iwconfig"); - dev->ifconfig = wiToolsPath("ifconfig"); - - if (!iwpriv) - { - fprintf(stderr, "Can't find wireless tools, exiting.\n"); - goto close_in; - } - - dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (0 > dev->fd_out) - { - perror("socket(PF_PACKET) failed at fd_out"); - goto close_in; - } - - /* figure out device type */ - - /* mac80211 radiotap injection - * detected based on interface called mon... - * since mac80211 allows multiple virtual interfaces - * - * note though that the virtual interfaces are ultimately using a - * single physical radio: that means for example they must all - * operate on the same channel - */ + dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); + if (0 > dev->fd_raw) + { + fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno)); + return 1; + } + if (dev->fd_raw >= FD_SETSIZE) + { + fprintf (stderr, "File descriptor too large for select (%d > %d)\n", + dev->fd_raw, FD_SETSIZE); + close (dev->fd_raw); + return 1; + } /* mac80211 stack detection */ - memset(strbuf, 0, sizeof(strbuf)); - snprintf(strbuf, sizeof(strbuf) - 1, - "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface); - - if (system(strbuf) == 0) - dev->drivertype = DT_MAC80211_RT; - - else - { - // At the moment only mac80211 tested - return 1; - } - -#ifdef DEBUG - fprintf(stderr, "Interface %s -> driver: %s\n", iface, - szaDriverTypes[dev->drivertype]); -#endif - - if (openraw(dev, iface, dev->fd_out, &dev->arptype_out, dev->pl_mac) != 0) - { - goto close_out; - } - - dev->fd_in = dev->fd_out; + ret = + snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", + iface); + if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) + { + fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface); + close (dev->fd_raw); + return 1; + } + strncpy (dev->iface, iface, IFNAMSIZ); + if (0 != openraw (dev)) + { + close (dev->fd_raw); + return 1; + } + return 0; +} - dev->arptype_in = dev->arptype_out; - return 0; - close_out: close(dev->fd_out); - close_in: close(dev->fd_in); +/** + * Function to test incoming packets mac for being our own. + * + * @param u8aIeeeHeader buffer of the packet + * @param dev the Hardware_Infos struct + * @return 0 if mac belongs to us, 1 if mac is for another target + */ +static int +mac_test (const struct ieee80211_frame *u8aIeeeHeader, + const struct Hardware_Infos *dev) +{ + if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE)) + return 1; + if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE)) + return 0; + if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE)) + return 0; return 1; } + +/** + * function to set the wlan header to make attacks more difficult + * @param u8aIeeeHeader pointer to the header of the packet + * @param dev pointer to the Hardware_Infos struct + */ static void -stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) +mac_set (struct ieee80211_frame *u8aIeeeHeader, + const struct Hardware_Infos *dev) { - struct Hardware_Infos * dev = cls; - struct sendbuf *write_pout = dev->write_pout; - struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1]; - int sendsize; - - unsigned char u8aRadiotap[] = - { 0x00, 0x00, // <-- radiotap version - 0x0c, 0x00, // <- radiotap header length - 0x04, 0x80, 0x00, 0x00, // <-- bitmap - 0x00, // <-- rate - 0x00, // <-- padding for natural alignment - 0x18, 0x00, // <-- TX flags - }; - - sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send) - - sizeof(struct GNUNET_MessageHeader); - - if ((sendsize) > MAXLINE * 2) - { - fprintf(stderr, "Function stdin_send: Packet too big for buffer\n"); - exit(1); - } - - if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)) - { - fprintf(stderr, "Function stdin_send: wrong packet type\n"); - exit(1); - } - - u8aRadiotap[8] = header->rate; - - switch (dev->drivertype) - { - - case DT_MAC80211_RT: - memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap)); - memcpy(write_pout->buf + sizeof(u8aRadiotap), write_pout->buf - + sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader), - sendsize); - sendsize += sizeof(u8aRadiotap); - - //usedrtap = 1; - break; - default: - break; - } + u8aIeeeHeader->i_fc[0] = 0x08; + u8aIeeeHeader->i_fc[1] = 0x00; + memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE); + memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE); - write_pout->size = sendsize; } -int -maketest(unsigned char * buf) +/** + * function to process the data from the stdin + * @param cls pointer to the device struct + * @param client not used + * @param hdr pointer to the start of the packet + */ +static void +stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { - unsigned char u8aRadiotap[] = - { 0x00, 0x00, // <-- radiotap version - 0x0c, 0x00, // <- radiotap header length - 0x04, 0x80, 0x00, 0x00, // <-- bitmap - 0x00, // <-- rate - 0x00, // <-- padding for natural alignment - 0x18, 0x00, // <-- TX flags - }; - - static const uint8_t u8aIeeeHeader[] = - { 0x08, 0x01, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; - // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data - // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; - 0x00, 0x00, // Duration/ID - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac1 - in this case receiver - 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac2 - in this case sender - 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid - 0x10, 0x86, //Sequence Control - }; - - static const char txt[] = "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211"; - - u8aRadiotap[8] = 8; - memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap)); - struct ieee80211_frame * ieee = (struct ieee80211_frame *) u8aIeeeHeader; - memcpy(buf + sizeof(u8aRadiotap), ieee, sizeof(u8aIeeeHeader)); - memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt)); - return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt); + struct Hardware_Infos *dev = cls; + struct sendbuf *write_pout = &dev->write_pout; + struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1]; + struct ieee80211_frame *wlanheader; + size_t sendsize; + + // struct? // FIXME: make nice... + struct RadioTapheader rtheader; + + rtheader.header.it_version = 0; + rtheader.header.it_len = htole16 (0x0c); + rtheader.header.it_present = htole32 (0x00008004); + rtheader.rate = 0x00; + rtheader.pad1 = 0x00; + rtheader.txflags = + htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); + + /* { 0x00, 0x00, <-- radiotap version + * 0x0c, 0x00, <- radiotap header length + * 0x04, 0x80, 0x00, 0x00, <-- bitmap + * 0x00, <-- rate + * 0x00, <-- padding for natural alignment + * 0x18, 0x00, <-- TX flags + * }; */ + + sendsize = ntohs (hdr->size); + if (sendsize < + sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) + { + fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n"); + exit (1); + } + sendsize -= + sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); + if (MAXLINE < sendsize) + { + fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); + exit (1); + } + if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) + { + fprintf (stderr, "Function stdin_send: wrong packet type\n"); + exit (1); + } + + rtheader.header.it_len = htole16 (sizeof (rtheader)); + rtheader.rate = header->rate; + memcpy (write_pout->buf, &rtheader, sizeof (rtheader)); + memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize); + /* payload contains MAC address, but we don't trust it, so we'll + * overwrite it with OUR MAC address again to prevent mischief */ + wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader)); + mac_set (wlanheader, dev); + write_pout->size = sendsize + sizeof (rtheader); } -int -hardwaremode(int argc, char *argv[]) +#if 0 +/** + * Function to make test packets with special options + * @param buf buffer to write the data to + * @param dev device to send the data from + * @return size of packet (what should be send) + */ +static int +maketest (unsigned char *buf, struct Hardware_Infos *dev) { + uint16_t *tmp16; + static uint16_t seqenz = 0; + static int first = 0; + + const int rate = 11000000; + static const char txt[] = + "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211"; + + unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version + 0x00, 0x00, // <- radiotap header length + 0x04, 0x80, 0x02, 0x00, // <-- bitmap + 0x00, // <-- rate + 0x00, // <-- padding for natural alignment + 0x10, 0x00, // <-- TX flags + 0x04 //retries + }; + + /*uint8_t u8aRadiotap[] = + * { + * 0x00, 0x00, // <-- radiotap version + * 0x19, 0x00, // <- radiotap header length + * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp + * 0x00, // <-- flags (Offset +0x10) + * 0x6c, // <-- rate (0ffset +0x11) + * 0x71, 0x09, 0xc0, 0x00, // <-- channel + * 0xde, // <-- antsignal + * 0x00, // <-- antnoise + * 0x01, // <-- antenna + * }; */ + + u8aRadiotap[8] = (rate / 500000); + u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap)); + + static struct ieee80211_frame u8aIeeeHeader; + + uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; + // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data + // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; + 0x00, 0x00, // Duration/ID + + //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver + 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver + 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender + //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4, + 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid + 0x10, 0x86, //Sequence Control + }; + if (0 == first) + { + memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame)); + memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE); + first = 1; + } + + tmp16 = (uint16_t *) u8aIeeeHeader.i_dur; + *tmp16 = + (uint16_t) + htole16 ((sizeof (txt) + + sizeof (struct ieee80211_frame) * 1000000) / rate + 290); + tmp16 = (uint16_t *) u8aIeeeHeader.i_seq; + *tmp16 = + (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) << + IEEE80211_SEQ_SEQ_SHIFT); + seqenz++; + + memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap)); + memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader)); + memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt, + sizeof (txt)); + return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt); - struct Hardware_Infos dev; - struct ifreq ifreq; - struct rx_info * rxinfo; - uint8_t * mac = dev.pl_mac; - int fdpin, fdpout; - - signal(SIGINT, &sigfunc_hw); - signal(SIGTERM, &sigfunc_hw); - - if (wlaninit(&dev, argv[1])) - { - return 1; - } - - printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", - ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3], - (int) mac[4], (int) mac[5]); +} +#endif - //return 0; +/** + * Function to start the hardware for the wlan helper + * @param argc number of arguments + * @param argv arguments + * @return returns one on error + */ +static int +hardwaremode (int argc, char *argv[]) +{ + uid_t uid; + struct Hardware_Infos dev; char readbuf[MAXLINE]; - int readsize = 0; struct sendbuf write_std; - write_std.size = 0; - write_std.pos = 0; - - struct sendbuf write_pout; - write_pout.size = 0; - write_pout.pos = 0; - - dev.write_pout = &write_pout; - - int ret = 0; - int maxfd = 0; - + ssize_t ret; + int maxfd; fd_set rfds; fd_set wfds; - struct timeval tv; int retval; + int stdin_open; + struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; - struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; - - fdpin = dev.fd_in; - fdpout = dev.fd_out; - - stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev); - - //send mac first - - write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac); - - //wait - tv.tv_sec = 2; - tv.tv_usec = 0; - retval = select(0, NULL, NULL, NULL, &tv); - - while (0 == closeprog) - { - - write_pout.size = maketest(write_pout.buf); - tv.tv_sec = 2; - tv.tv_usec = 0; - retval = select(0, NULL, NULL, NULL, &tv); - - maxfd = 0; - - //set timeout - tv.tv_sec = 5; - tv.tv_usec = 0; - - FD_ZERO(&rfds); - // if output queue is empty - if (0 == write_pout.size) - { - FD_SET(STDIN_FILENO, &rfds); - - } - if (0 == write_std.size) - { - //FD_SET(fdpin, &rfds); - //maxfd = fdpin; - } - FD_ZERO(&wfds); - // if there is something to write - if (0 < write_std.size) - { - FD_SET(STDOUT_FILENO, &wfds); - maxfd = MAX(maxfd, STDOUT_FILENO); - } - - if (0 < write_pout.size) - { - FD_SET(fdpout, &wfds); - maxfd = MAX(maxfd, fdpout); - } - - retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv); - - if (-1 == retval && EINTR == errno) - { - continue; - } - if (0 > retval) - { - fprintf(stderr, "select failed: %s\n", strerror(errno)); - exit(1); - } - - if (FD_ISSET(STDOUT_FILENO, &wfds)) - { - ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, - write_std.size - write_std.pos); - - if (0 > ret) - { - closeprog = 1; - fprintf(stderr, "Write ERROR to STDOUT\n"); - exit(1); - } - else - { - write_std.pos += ret; - // check if finished - if (write_std.pos == write_std.size) - { - write_std.pos = 0; - write_std.size = 0; - } - } - } - - if (FD_ISSET(fdpout, &wfds)) - { - - ret = linux_write(&dev, write_pout.buf, write_pout.size); - //ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size - // - write_pout.pos); - - if (0 > ret) - { - closeprog = 1; - fprintf(stderr, "Write ERROR to fdpout\n"); - } - else - { - write_pout.pos += ret; - // check if finished - if (write_pout.pos != write_pout.size && ret != 0) - { - closeprog = 1; - fprintf(stderr, "Write ERROR packet not in one piece send: %u, %u\n", write_pout.pos, write_pout.size); - } - else if (write_pout.pos == write_pout.size) - { - write_pout.pos = 0; - write_pout.size = 0; - } - - } - } - - if (FD_ISSET(STDIN_FILENO, &rfds)) - { - readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf)); - - if (0 > readsize) - { - closeprog = 1; - fprintf(stderr, "Read ERROR to STDIN_FILENO\n"); - } - else if (0 < readsize) - { - GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize, - GNUNET_NO, GNUNET_NO); - - } - else - { - //eof - closeprog = 1; - } - } - - if (FD_ISSET(fdpin, &rfds)) - { - rxinfo = (struct rx_info *) (write_pout.buf - + sizeof(struct GNUNET_MessageHeader)); - readsize = linux_read(&dev, (unsigned char *) readbuf - + sizeof(struct rx_info) + sizeof(struct GNUNET_MessageHeader), - sizeof(readbuf) - sizeof(struct rx_info) - - sizeof(struct GNUNET_MessageHeader), rxinfo); - //readsize = read(fdpin, readbuf, sizeof(readbuf)); - - if (0 > readsize) - { - closeprog = 1; - fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno)); - closeprog = 1; - } - else if (0 < readsize) - { - - } - else - { - //eof - //closeprog = 1; - } - } - - } + if (0 != wlaninit (&dev, argv[1])) + return 1; + uid = getuid (); + if (0 != setresuid (uid, uid, uid)) + { + fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); + /* not critical, continue anyway */ + } - return 0; + dev.write_pout.size = 0; + dev.write_pout.pos = 0; + stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev); -} + /* send mac to STDOUT first */ + write_std.pos = 0; + write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac); + stdin_open = 1; -int -main(int argc, char *argv[]) -{ - if (3 != argc) + while (1) + { + maxfd = -1; + FD_ZERO (&rfds); + if ((0 == dev.write_pout.size) && (1 == stdin_open)) { - fprintf( - stderr, - "This program must be started with the interface and the operating mode as argument.\n"); - return 1; + FD_SET (STDIN_FILENO, &rfds); + maxfd = MAX (maxfd, STDIN_FILENO); } - - if (strstr(argv[2], "1") || strstr(argv[2], "2")) + if (0 == write_std.size) { - - return testmode(argc, argv); + FD_SET (dev.fd_raw, &rfds); + maxfd = MAX (maxfd, dev.fd_raw); } - else + FD_ZERO (&wfds); + if (0 < write_std.size) { - hardwaremode(argc, argv); + FD_SET (STDOUT_FILENO, &wfds); + maxfd = MAX (maxfd, STDOUT_FILENO); } - -#if 0 - u8 u8aSendBuffer[500]; - char szErrbuf[PCAP_ERRBUF_SIZE]; - int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0; - int nOrdinal = 0, r, nDelay = 100000; - int nRateIndex = 0, retval, bytes; - pcap_t *ppcap = NULL; - struct bpf_program bpfprogram; - char * szProgram = "", fBrokenSocket = 0; - u16 u16HeaderLen; - char szHostname[PATH_MAX]; - - if (gethostname(szHostname, sizeof (szHostname) - 1)) + if (0 < dev.write_pout.size) { - perror("unable to get hostname"); + FD_SET (dev.fd_raw, &wfds); + maxfd = MAX (maxfd, dev.fd_raw); } - szHostname[sizeof (szHostname) - 1] = '\0'; - - printf("Packetspammer (c)2007 Andy Green GPL2\n"); - - while (1) + retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); + if ((-1 == retval) && (EINTR == errno)) + continue; + if (0 > retval) { - int nOptionIndex; - static const struct option optiona[] = - { - { "delay", required_argument, NULL, 'd'}, - { "fcs", no_argument, &flagMarkWithFCS, 1}, - { "help", no_argument, &flagHelp, 1}, - { "verbose", no_argument, &flagVerbose, 1}, - { 0, 0, 0, 0} - }; - int c = getopt_long(argc, argv, "d:hf", - optiona, &nOptionIndex); - - if (c == -1) + fprintf (stderr, "select failed: %s\n", strerror (errno)); break; - switch (c) - { - case 0: // long option - break; - - case 'h': // help - usage(); - - case 'd': // delay - nDelay = atoi(optarg); - break; - - case 'f': // mark as FCS attached - flagMarkWithFCS = 1; - break; - - case 'v': //Verbose / readable output to cout - flagVerbose = 1; - break; - - default: - printf("unknown switch %c\n", c); - usage(); - break; - } } - if (optind >= argc) - usage(); - - // open the interface in pcap - - szErrbuf[0] = '\0'; - ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf); - if (ppcap == NULL) + if (FD_ISSET (STDOUT_FILENO, &wfds)) { - printf("Unable to open interface %s in pcap: %s\n", - argv[optind], szErrbuf); - return (1); + ret = + write (STDOUT_FILENO, write_std.buf + write_std.pos, + write_std.size - write_std.pos); + if (0 > ret) + { + fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); + break; + } + write_std.pos += ret; + if (write_std.pos == write_std.size) + { + write_std.pos = 0; + write_std.size = 0; + } } - //get mac from interface - - /*int sock, j, k; - char mac[32]; - - sock=socket(PF_INET, SOCK_STREAM, 0); - if (-1==sock) { - perror("can not open socket\n"); - return 1; - } - - if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) { - perror("ioctl(SIOCGIFHWADDR) "); - return 1; - } - for (j=0, k=0; j<6; j++) { - k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X", - (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]); - } - mac[sizeof(mac)-1]='\0'; - */ - - //get header type - nLinkEncap = pcap_datalink(ppcap); - nCaptureHeaderLength = 0; - - switch (nLinkEncap) + if (FD_ISSET (dev.fd_raw, &wfds)) { - - case DLT_PRISM_HEADER: - printf("DLT_PRISM_HEADER Encap\n"); - nCaptureHeaderLength = 0x40; - n80211HeaderLength = 0x20; // ieee80211 comes after this - szProgram = "radio[0x4a:4]==0x13223344"; - break; - - case DLT_IEEE802_11_RADIO: - printf("DLT_IEEE802_11_RADIO Encap\n"); - nCaptureHeaderLength = 0x40; - n80211HeaderLength = 0x18; // ieee80211 comes after this - szProgram = "ether[0x0a:4]==0x13223344"; - break; - - default: - printf("!!! unknown encapsulation on %s !\n", argv[1]); - return (1); - + ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size); + if (0 > ret) + { + fprintf (stderr, + "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n", + __LINE__, strerror (errno), dev.write_pout.size); + break; + } + dev.write_pout.pos += ret; + if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0)) + { + fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n", + __LINE__, dev.write_pout.pos, dev.write_pout.size); + break; + } + if (dev.write_pout.pos == dev.write_pout.size) + { + dev.write_pout.pos = 0; + dev.write_pout.size = 0; + } } - if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) - { - puts(szProgram); - puts(pcap_geterr(ppcap)); - return (1); - } - else + if (FD_ISSET (STDIN_FILENO, &rfds)) { - if (pcap_setfilter(ppcap, &bpfprogram) == -1) - { - puts(szProgram); - puts(pcap_geterr(ppcap)); - } - else - { - printf("RX Filter applied\n"); - } - pcap_freecode(&bpfprogram); + ret = read (STDIN_FILENO, readbuf, sizeof (readbuf)); + if (0 > ret) + { + fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno)); + break; + } + if (0 == ret) + { + /* stop reading... */ + stdin_open = 0; + } + GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO, + GNUNET_NO); } - pcap_setnonblock(ppcap, 1, szErrbuf); - - printf(" (delay between packets %dus)\n", nDelay); - - memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer)); - - while (!fBrokenSocket) + if (FD_ISSET (dev.fd_raw, &rfds)) { - u8 * pu8 = u8aSendBuffer; - struct pcap_pkthdr * ppcapPacketHeader = NULL; - struct ieee80211_radiotap_iterator rti; - PENUMBRA_RADIOTAP_DATA prd; - //init of the values - prd.m_nRate = 255; - prd.m_nChannel = 255; - prd.m_nAntenna = 255; - prd.m_nRadiotapFlags = 255; - u8 * pu8Payload = u8aSendBuffer; - int n, nRate; - - // receive - - retval = pcap_next_ex(ppcap, &ppcapPacketHeader, - (const u_char**) &pu8Payload); - - if (retval < 0) - { - fBrokenSocket = 1; - continue; - } - - if (retval != 1) - goto do_tx; - - u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8)); - - printf("rtap: "); - Dump(pu8Payload, u16HeaderLen); - - if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength)) - continue; - - bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength); - if (bytes < 0) - continue; - - if (ieee80211_radiotap_iterator_init(&rti, - (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0) - continue; - - while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) - { - - switch (rti.this_arg_index) - { - case IEEE80211_RADIOTAP_RATE: - prd.m_nRate = (*rti.this_arg); - break; - - case IEEE80211_RADIOTAP_CHANNEL: - prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg)); - prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2))); - break; - - case IEEE80211_RADIOTAP_ANTENNA: - prd.m_nAntenna = (*rti.this_arg) + 1; - break; - - case IEEE80211_RADIOTAP_FLAGS: - prd.m_nRadiotapFlags = *rti.this_arg; - break; - - } - } - - pu8Payload += u16HeaderLen + n80211HeaderLength; - - if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS) - bytes -= 4; - - printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, " - "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1), - prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000) - * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags); - - Dump(pu8Payload, bytes); - - do_tx: - - // transmit + struct GNUNET_MessageHeader *header; + struct Radiotap_rx *rxinfo; + struct ieee80211_frame *datastart; + + header = (struct GNUNET_MessageHeader *) write_std.buf; + rxinfo = (struct Radiotap_rx *) &header[1]; + datastart = (struct ieee80211_frame *) &rxinfo[1]; + ret = + linux_read (&dev, (unsigned char *) datastart, + sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - + sizeof (struct GNUNET_MessageHeader), rxinfo); + if (0 > ret) + { + fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); + break; + } + if ((0 < ret) && (0 == mac_test (datastart, &dev))) + { + write_std.size = + ret + sizeof (struct GNUNET_MessageHeader) + + sizeof (struct Radiotap_rx); + header->size = htons (write_std.size); + header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); + } + } - memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader)); - if (flagMarkWithFCS) - pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS; - nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++]; - if (nRateIndex >= sizeof(u8aRatesToUse)) - nRateIndex = 0; - pu8 += sizeof(u8aRadiotapHeader); + } + /* Error handling, try to clean up a bit at least */ + GNUNET_SERVER_mst_destroy (stdin_mst); + close (dev.fd_raw); + return 1; +} - memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader)); - pu8 += sizeof(u8aIeeeHeader); +/** + * main function of the helper + * @param argc number of arguments + * @param argv arguments + * @return 0 on success, 1 on error + */ +int +main (int argc, char *argv[]) +{ + if (2 != argc) + { + fprintf (stderr, + "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n", + __TIMESTAMP__); + fprintf (stderr, "Usage: interface-name\n" "\n"); + return 1; + } + return hardwaremode (argc, argv); +} - pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d" - "broadcast packet" - "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname); - r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer); - if (r != (pu8 - u8aSendBuffer)) - { - perror("Trouble injecting packet"); - return (1); - } - if (nDelay) - usleep(nDelay); - } +/* + * Copyright (c) 2008, Thomas d'Otreppe + * + * Common OSdep stuff + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ -#endif - return (0); +/** + * Return the frequency in Mhz from a channel number + * @param channel number of the channel + * @return frequency of the channel + */ +int +getFrequencyFromChannel (int channel) +{ + static int frequencies[] = { + -1, // No channel 0 + 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, + 2472, 2484, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Nothing from channel 15 to 34 (exclusive) + 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225, + 5230, 5235, 5240, 5245, + 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305, + 5310, 5315, 5320, 5325, + 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385, + 5390, 5395, 5400, 5405, + 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465, + 5470, 5475, 5480, 5485, + 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545, + 5550, 5555, 5560, 5565, + 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625, + 5630, 5635, 5640, 5645, + 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705, + 5710, 5715, 5720, 5725, + 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785, + 5790, 5795, 5800, 5805, + 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865, + 5870, 5875, 5880, 5885, + 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945, + 5950, 5955, 5960, 5965, + 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025, + 6030, 6035, 6040, 6045, + 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100 + }; + + return ((channel > 0) && + (channel < + sizeof (frequencies) / sizeof (int))) ? frequencies[channel] : -1; } +/** + * Return the channel from the frequency (in Mhz) + * @param frequency of the channel + * @return number of the channel + */ +int +getChannelFromFrequency (int frequency) +{ + if (frequency >= 2412 && frequency <= 2472) + return (frequency - 2407) / 5; + else if (frequency == 2484) + return 14; + else if (frequency >= 5000 && frequency <= 6100) + return (frequency - 5000) / 5; + else + return -1; +}