X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-transport-wlan-helper.c;h=25e55e510a583ca3287aa457608a10addb84f999;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=05fab4758e4d559a92c51b57b05d0126fa1efd25;hpb=f1e46a71318eea0fc45e8142c7c6dbdfa0436c8a;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 05fab4758..25e55e510 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c @@ -1,22 +1,22 @@ /* - This file is part of GNUnet. - (C) 2010 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 - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet 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 GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ + This file is part of GNUnet. + (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 + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet 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 GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ /** * @file src/transport/gnunet-transport-wlan-helper.c @@ -28,8 +28,41 @@ * gnunet */ +/** + * parts taken from aircrack-ng, parts changend. + */ -#include "platform.h" +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +/* + //#include + #include + #include + #include + */ +//#include "platform.h" #include "gnunet_constants.h" #include "gnunet_os_lib.h" #include "gnunet_transport_plugin.h" @@ -38,1024 +71,970 @@ #include "plugin_transport_wlan.h" #include "gnunet_common.h" #include "gnunet-transport-wlan-helper.h" -#include "ieee80211_radiotap.h" -#include -#include -#include -#include +#include "gnunet_crypto_lib.h" +#include "wlan/radiotap-parser.h" +/* radiotap-parser defines types like u8 that + * ieee80211_radiotap.h needs + * + * we use our local copy of ieee80211_radiotap.h + * + * - since we can't support extensions we don't understand + * - since linux does not include it in userspace headers + */ +#include "wlan/ieee80211_radiotap.h" +#include "wlan/crctable_osdep.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 +#define DEBUG 1 +#define MAC_ADDR_SIZE 6 -//#include "radiotap.h" - -// mac of this node -char mac[] = - { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 }; - -/* 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 -typedef struct { - int m_nChannel; - int m_nChannelFlags; - int m_nRate; - int m_nAntenna; - int m_nRadiotapFlags; -} __attribute__((packed)) PENUMBRA_RADIOTAP_DATA; +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ -void -Dump(u8 * pu8, int nLength) +/* + * generic definitions for IEEE 802.11 frames + */ +struct ieee80211_frame { - 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'; - - 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); - - 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); -} - + 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 -usage() +/** + * struct for storing the information of the hardware + */ +struct Hardware_Infos { - 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); -} -int flagHelp = 0, flagMarkWithFCS = 0; -int flagVerbose = 0; + /** + * send buffer + */ + struct sendbuf write_pout; + /** + * file descriptor for the raw socket + */ + int fd_raw; + + int arptype_in; + + /** + * Name of the interface, not necessarily 0-terminated (!). + */ + char iface[IFNAMSIZ]; + unsigned char pl_mac[MAC_ADDR_SIZE]; +}; +struct RadioTapheader +{ + struct ieee80211_radiotap_header header; + u8 rate; + u8 pad1; + u16 txflags; +}; -/* - * Radiotap parser - * - * Copyright 2007 Andy Green - */ +// FIXME: inline? +int +getChannelFromFrequency (int frequency); +// FIXME: make nice... /** - * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization - * @param iterator: radiotap_iterator to initialize - * @param radiotap_header: radiotap header to parse - * @param max_length: total length we can parse into (eg, whole packet length) - * - * @return 0 or a negative error code if there is a problem. - * - * This function initializes an opaque iterator struct which can then - * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap - * argument which is present in the header. It knows about extended - * present headers and handles them. - * - * How to use: - * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator - * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) - * checking for a good 0 return code. Then loop calling - * __ieee80211_radiotap_iterator_next()... it returns either 0, - * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem. - * The iterator's this_arg member points to the start of the argument - * associated with the current argument index that is present, which can be - * found in the iterator's this_arg_index member. This arg index corresponds - * to the IEEE80211_RADIOTAP_... defines. - * - * Radiotap header length: - * You can find the CPU-endian total radiotap header length in - * iterator->max_length after executing ieee80211_radiotap_iterator_init() - * successfully. - * - * Example code: - * See Documentation/networking/radiotap-headers.txt + * 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 */ - -int ieee80211_radiotap_iterator_init( - struct ieee80211_radiotap_iterator *iterator, - struct ieee80211_radiotap_header *radiotap_header, - int max_length) +static unsigned long +calc_crc_osdep (unsigned char *buf, int len) { - /* Linux only supports version 0 radiotap format */ - if (radiotap_header->it_version) - return -EINVAL; - - /* sanity check for allowed length and radiotap length field */ - if (max_length < le16_to_cpu(radiotap_header->it_len)) - return -EINVAL; - - iterator->rtheader = radiotap_header; - iterator->max_length = le16_to_cpu(radiotap_header->it_len); - iterator->arg_index = 0; - iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present); - iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header); - iterator->this_arg = 0; - - /* find payload start allowing for extended bitmap(s) */ - - if (unlikely(iterator->bitmap_shifter & (1<arg)) & - (1<arg += sizeof(u32); - - /* - * check for insanity where the present bitmaps - * keep claiming to extend up to or even beyond the - * stated radiotap header length - */ - - if (((ulong)iterator->arg - - (ulong)iterator->rtheader) > iterator->max_length) - return -EINVAL; - } - - iterator->arg += sizeof(u32); - - /* - * no need to check again for blowing past stated radiotap - * header length, because ieee80211_radiotap_iterator_next - * checks it before it is dereferenced - */ - } - - /* we are all initialized happily */ - - return 0; + unsigned long crc = 0xFFFFFFFF; + + for (; len > 0; len--, buf++) + crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8); + + return (~crc); } +/* CRC checksum verification routine */ +// FIXME: make nice... /** - * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg - * @param iterator: radiotap_iterator to move to next arg (if any) - * - * @return 0 if there is an argument to handle, - * -ENOENT if there are no more args or -EINVAL - * if there is something else wrong. - * - * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*) - * in this_arg_index and sets this_arg to point to the - * payload for the field. It takes care of alignment handling and extended - * present fields. this_arg can be changed by the caller (eg, - * incremented to move inside a compound argument like - * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in - * little-endian format whatever the endianess of your CPU. + * 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 */ - -int ieee80211_radiotap_iterator_next( - struct ieee80211_radiotap_iterator *iterator) +static int +check_crc_buf_osdep (unsigned char *buf, int len) { + unsigned long crc; - /* - * small length lookup table for all radiotap types we heard of - * starting from b0 in the bitmap, so we can walk the payload - * area of the radiotap header - * - * There is a requirement to pad args, so that args - * of a given length must begin at a boundary of that length - * -- but note that compound args are allowed (eg, 2 x u16 - * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not - * a reliable indicator of alignment requirement. - * - * upper nybble: content alignment for arg - * lower nybble: content length for arg - */ - - static const u8 rt_sizes[] = { - [IEEE80211_RADIOTAP_TSFT] = 0x88, - [IEEE80211_RADIOTAP_FLAGS] = 0x11, - [IEEE80211_RADIOTAP_RATE] = 0x11, - [IEEE80211_RADIOTAP_CHANNEL] = 0x24, - [IEEE80211_RADIOTAP_FHSS] = 0x22, - [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11, - [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11, - [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22, - [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22, - [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22, - [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11, - [IEEE80211_RADIOTAP_ANTENNA] = 0x11, - [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11, - [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11 - /* - * add more here as they are defined in - * include/net/ieee80211_radiotap.h - */ - }; - - /* - * for every radiotap entry we can at - * least skip (by knowing the length)... - */ - - while (iterator->arg_index < sizeof(rt_sizes)) { - int hit = 0; - int pad; - - if (!(iterator->bitmap_shifter & 1)) - goto next_entry; /* arg not present */ - - /* - * arg is present, account for alignment padding - * 8-bit args can be at any alignment - * 16-bit args must start on 16-bit boundary - * 32-bit args must start on 32-bit boundary - * 64-bit args must start on 64-bit boundary - * - * note that total arg size can differ from alignment of - * elements inside arg, so we use upper nybble of length - * table to base alignment on - * - * also note: these alignments are ** relative to the - * start of the radiotap header **. There is no guarantee - * that the radiotap header itself is aligned on any - * kind of boundary. - */ - - pad = (((ulong)iterator->arg) - - ((ulong)iterator->rtheader)) & - ((rt_sizes[iterator->arg_index] >> 4) - 1); - - if (pad) - iterator->arg_index += - (rt_sizes[iterator->arg_index] >> 4) - pad; - - /* - * this is what we will return to user, but we need to - * move on first so next call has something fresh to test - */ - iterator->this_arg_index = iterator->arg_index; - iterator->this_arg = iterator->arg; - hit = 1; - - /* internally move on the size of this arg */ - iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; - - /* - * check for insanity where we are given a bitmap that - * claims to have more arg content than the length of the - * radiotap section. We will normally end up equalling this - * max_length on the last arg, never exceeding it. - */ - - if (((ulong)iterator->arg - (ulong)iterator->rtheader) > - iterator->max_length) - return -EINVAL; - - next_entry: - iterator->arg_index++; - if (unlikely((iterator->arg_index & 31) == 0)) { - /* completed current u32 bitmap */ - if (iterator->bitmap_shifter & 1) { - /* b31 was set, there is more */ - /* move to next u32 bitmap */ - iterator->bitmap_shifter = - le32_to_cpu(*iterator->next_bitmap); - iterator->next_bitmap++; - } else { - /* no more bitmaps: end */ - iterator->arg_index = sizeof(rt_sizes); - } - } else { /* just try the next bit */ - iterator->bitmap_shifter >>= 1; - } - - /* if we found a valid arg earlier, return it now */ - if (hit) - return 0; - } - - /* we don't know how to handle any more args, we're done */ - return -ENOENT; -} + if (0 > len) + return 0; -#define FIFO_FILE1 "/tmp/MYFIFOin" -#define FIFO_FILE2 "/tmp/MYFIFOout" -#define MAXLINE 20 - -static int first; -static int closeprog; - -static void -sigfunc(int sig) -{ - closeprog = 1; - unlink(FIFO_FILE1); - unlink(FIFO_FILE2); + 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]); } -struct sendbuf { - int pos; - int size; - char buf[MAXLINE * 2]; -}; -static void -stdin_send (void *cls, - void *client, - const struct GNUNET_MessageHeader *hdr) +// 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) { - struct sendbuf *write_pout = cls; - int sendsize = ntohs(hdr->size) - sizeof(struct RadiotapHeader) ; - struct GNUNET_MessageHeader newheader; + struct iwreq wrq; + int fd, frequency; + int chan = 0; - GNUNET_assert(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA == ntohs(hdr->type)); - GNUNET_assert (sendsize + write_pout->size < MAXLINE *2); + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); - newheader.size = htons(sendsize); - newheader.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); + fd = dev->fd_raw; + if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) + return (-1); + frequency = wrq.u.freq.m; + if (100000000 < frequency) + frequency /= 100000; + else if (1000000 < frequency) + frequency /= 1000; - memcpy(write_pout->buf + write_pout->size, &newheader, sizeof(struct GNUNET_MessageHeader)); - write_pout->size += sizeof(struct GNUNET_MessageHeader); + if (1000 < frequency) + chan = getChannelFromFrequency (frequency); + else + chan = frequency; - memcpy(write_pout->buf + write_pout->size, hdr + sizeof(struct RadiotapHeader) + sizeof(struct GNUNET_MessageHeader), sizeof(struct GNUNET_MessageHeader)); - write_pout->size += sendsize; + return chan; } -static void -file_in_send (void *cls, - void *client, - const struct GNUNET_MessageHeader *hdr) + +// 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) { - struct sendbuf * write_std = cls; - int sendsize = ntohs(hdr->size); + unsigned char tmpbuf[buf_size]; + ssize_t caplen; + int n, got_signal, got_noise, got_channel, fcs_removed; + + n = got_signal = got_noise = got_channel = fcs_removed = 0; + + caplen = read (dev->fd_raw, tmpbuf, buf_size); + if (0 > caplen) + { + if (EAGAIN == errno) + return 0; + fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno)); + return -1; + } + + memset (buf, 0, buf_size); + memset (ri, 0, sizeof (*ri)); + + switch (dev->arptype_in) + { + case ARPHRD_IEEE80211_PRISM: + { + /* skip the prism header */ + if (tmpbuf[7] == 0x40) + { + /* 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; + } + else + { + 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); + } - GNUNET_assert(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA == ntohs(hdr->type)); - GNUNET_assert (sendsize + write_std->size < MAXLINE *2); + if (n < 8 || n >= caplen) + return (0); + } + break; - memcpy(write_std->buf + write_std->size, hdr, sendsize); - write_std->size += sendsize; -} + case ARPHRD_IEEE80211_FULL: + { + struct ieee80211_radiotap_iterator iterator; + struct ieee80211_radiotap_header *rthdr; -int -testmode(int argc, char *argv[]) -{ - struct stat st; - int erg; + rthdr = (struct ieee80211_radiotap_header *) tmpbuf; - FILE *fpin; - FILE *fpout; + if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) + return (0); - int fdpin; - int fdpout; + /* go through the radiotap arguments we have been given + * by the driver + */ - //make the fifos if needed - if (0 != stat(FIFO_FILE1, &st)) + while (ieee80211_radiotap_iterator_next (&iterator) >= 0) { - if (0 == stat(FIFO_FILE2, &st)) - { - fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not"); - exit(1); - } - umask(0); - erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0); - erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0); + switch (iterator.this_arg_index) + { - } - else - { + case IEEE80211_RADIOTAP_TSFT: + ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg)); + break; - if (0 != stat(FIFO_FILE2, &st)) + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + if (!got_signal) { - fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not"); - exit(1); - } + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; - } + got_signal = 1; + } + break; - if (strstr(argv[2], "1")) - { - //fprintf(stderr, "First\n"); - first = 1; - fpin = fopen(FIFO_FILE1, "r"); - if (NULL == fpin) + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + if (!got_signal) { - fprintf(stderr, "fopen of read FIFO_FILE1"); - exit(1); + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; + + got_signal = 1; } - if (NULL == (fpout = fopen(FIFO_FILE2, "w"))) + break; + + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + if (!got_noise) { - fprintf(stderr, "fopen of write FIFO_FILE2"); - exit(1); + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; + + got_noise = 1; } + break; - } - else - { - first = 0; - //fprintf(stderr, "Second\n"); - if (NULL == (fpout = fopen(FIFO_FILE1, "w"))) + case IEEE80211_RADIOTAP_DB_ANTNOISE: + if (!got_noise) { - fprintf(stderr, "fopen of write FIFO_FILE1"); - exit(1); + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; + + got_noise = 1; } - if (NULL == (fpin = fopen(FIFO_FILE2, "r"))) + 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) { - fprintf(stderr, "fopen of read FIFO_FILE2"); - exit(1); + fcs_removed = 1; + caplen -= 4; } - } + if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) + return (0); - fdpin = fileno(fpin); - if (fdpin >= FD_SETSIZE) - { - fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin, - (unsigned int) FD_SETSIZE); - close(fdpin); - return -1; + 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 caplen; +} - fdpout = fileno(fpout); - if (fdpout >= FD_SETSIZE) +/** + * 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) +{ + struct ifreq ifr; + struct iwreq wrq; + struct packet_mreq mr; + 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; + } + + /* lookup the hardware type */ + memset (&sll, 0, sizeof (sll)); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = ifr.ifr_ifindex; + 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, 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 (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) { - fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout, - (unsigned int) FD_SETSIZE); - close(fdpout); - return -1; - + fprintf (stderr, + "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; } + } + + /* 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; + } + + /* 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)); + 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; + } + + return 0; +} - signal(SIGINT, &sigfunc); - signal(SIGTERM, &sigfunc); - - 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; - - int ret = 0; - int maxfd = 0; - - fd_set rfds; - fd_set wfds; - struct timeval tv; - int retval; - - - - struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; - struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst; +/** + * 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 strbuf[512]; + struct stat sbuf; + int ret; + + 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 */ + 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; +} - stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout); - file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std); - //send mac first +/** + * 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; +} - struct Wlan_Helper_Control_Message macmsg; - //Send random mac address - macmsg.mac.mac[0] = 0x13; - macmsg.mac.mac[1] = 0x22; - macmsg.mac.mac[2] = 0x33; - macmsg.mac.mac[3] = 0x44; - macmsg.mac.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 255); - macmsg.mac.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 255); - macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message)); - macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL); +/** + * 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 +mac_set (struct ieee80211_frame *u8aIeeeHeader, + const struct Hardware_Infos *dev) +{ + 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); - memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message)); - write_std.size = sizeof(struct Wlan_Helper_Control_Message); +} - /* - //wait - tv.tv_sec = 2; - tv.tv_usec = 0; - retval = select(0, NULL, NULL, NULL, &tv); +/** + * 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) +{ + 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); +} +#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); - tv.tv_sec = 3; - tv.tv_usec = 0; - // if there is something to write - FD_ZERO(&wfds); - FD_SET(STDOUT_FILENO, &wfds); +} +#endif - retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv); - if (FD_ISSET(STDOUT_FILENO, &wfds)) +/** + * 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]; + struct sendbuf write_std; + ssize_t ret; + int maxfd; + fd_set rfds; + fd_set wfds; + int retval; + int stdin_open; + struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; + + 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 */ + } + + 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; + + while (1) + { + maxfd = -1; + FD_ZERO (&rfds); + if ((0 == dev.write_pout.size) && (1 == stdin_open)) { - ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - - write_std.pos); + FD_SET (STDIN_FILENO, &rfds); + maxfd = MAX (maxfd, STDIN_FILENO); + } + if (0 == write_std.size) + { + FD_SET (dev.fd_raw, &rfds); + maxfd = MAX (maxfd, dev.fd_raw); + } + FD_ZERO (&wfds); + if (0 < write_std.size) + { + FD_SET (STDOUT_FILENO, &wfds); + maxfd = MAX (maxfd, STDOUT_FILENO); + } + if (0 < dev.write_pout.size) + { + FD_SET (dev.fd_raw, &wfds); + maxfd = MAX (maxfd, dev.fd_raw); + } + retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); + if ((-1 == retval) && (EINTR == errno)) + continue; + if (0 > retval) + { + fprintf (stderr, "select failed: %s\n", strerror (errno)); + break; + } + 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"); - 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; - } - } + { + 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; + } } - memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message)); - write_std.size = sizeof(struct Wlan_Helper_Control_Message); - */ - - //wait - tv.tv_sec = 2; - tv.tv_usec = 0; - retval = select(0, NULL, NULL, NULL, &tv); - - while (0 == closeprog) + if (FD_ISSET (dev.fd_raw, &wfds)) { - - 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); + 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; } - - if (0 < write_pout.size){ - FD_SET(fdpout, &wfds); - maxfd = MAX(maxfd, fdpout); + 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; } - - - 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"); - 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 = 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"); - exit(1); - } - else - { - write_pout.pos += ret; - // check if finished - 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"); - exit(1); - } - else - { - GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize, - GNUNET_NO, GNUNET_NO); - - } - } - - if (FD_ISSET(fdpin, &rfds)) - { - readsize = read(fdpin, readbuf, sizeof(readbuf)); - - if (0 > readsize) - { - closeprog = 1; - fprintf(stderr, "Read ERROR to fdpin"); - exit(1); - } - else - { - GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize, - GNUNET_NO, GNUNET_NO); - - } - } - } - //clean up - fclose(fpout); - fclose(fpin); + if (FD_ISSET (STDIN_FILENO, &rfds)) + { + 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); + } - if (1 == first) + if (FD_ISSET (dev.fd_raw, &rfds)) { - unlink(FIFO_FILE1); - unlink(FIFO_FILE2); + 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); + } } - return (0); + } + /* Error handling, try to clean up a bit at least */ + GNUNET_SERVER_mst_destroy (stdin_mst); + close (dev.fd_raw); + return 1; } - +/** + * 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[]) +main (int argc, char *argv[]) { - if (3 != argc) - { - fprintf( - stderr, - "This program must be started with the interface and the operating mode as argument.\n"); - return 1; - } - - if (strstr(argv[2], "1") || strstr(argv[2], "2")) - { - - return testmode(argc, argv); - } - -#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)) { - perror("unable to get hostname"); - } - szHostname[sizeof (szHostname) - 1] = '\0'; - - - printf("Packetspammer (c)2007 Andy Green GPL2\n"); - - while (1) { - 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) - 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) { - printf("Unable to open interface %s in pcap: %s\n", - argv[optind], szErrbuf); - return (1); - } - - //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;home/mwachs/gnb/bin/ - - switch (nLinkEncap) { - - 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); - - } - - if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) { - puts(szProgram); - puts(pcap_geterr(ppcap)); - return (1); - } else { - if (pcap_setfilter(ppcap, &bpfprogram) == -1) { - puts(szProgram); - puts(pcap_geterr(ppcap)); - } else { - printf("RX Filter applied\n"); - } - pcap_freecode(&bpfprogram); - } - - pcap_setnonblock(ppcap, 1, szErrbuf); - - printf(" (delay between packets %dus)\n", nDelay); - - memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer)); - - while (!fBrokenSocket) { - 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 - - 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); - - memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader)); - pu8 += sizeof (u8aIeeeHeader); - - 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); - } + 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); +} +/* + * 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; +}