/*
- 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-wlan.c
+ * @file src/transport/gnunet-transport-wlan-helper.c
* @brief wlan layer two server; must run as root (SUID will do)
* This code will work under GNU/Linux only.
* @author David Brodski
* This program serves as the mediator between the wlan interface and
* gnunet
*/
-#include "gnunet-transport-wlan-helper.h"
-#include "plugin_transport_wlan.h"
-#include "ieee80211_radiotap.h"
-
-#include <pcap.h>
-
-//#include "radiotap.h"
-
-// broadcast mac
-static const char macbc[] = "13223344";
-
-// mac of this node
-char mac[] = "13223355";
-
-/* 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;
-
-void
-Dump(u8 * pu8, int nLength)
-{
- 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);
-}
-
-
-void
-usage(void)
-{
- printf(
- "Usage: wlan-hwd [options] <interface>\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;
+#define _GNU_SOURCE
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <netpacket/packet.h>
+#include <linux/if_ether.h>
+#include <linux/if.h>
+#include <linux/wireless.h>
+#include <netinet/in.h>
+#include <linux/if_tun.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+//#include <sys/utsname.h>
+#include <sys/param.h>
/*
- * Radiotap parser
- *
- * Copyright 2007 Andy Green <andy@warmcat.com>
+ //#include <resolv.h>
+ #include <string.h>
+ #include <utime.h>
+ #include <getopt.h>
*/
+//#include "platform.h"
+#include "gnunet_constants.h"
+#include "gnunet_os_lib.h"
+#include "gnunet_transport_plugin.h"
+#include "transport.h"
+#include "gnunet_util_lib.h"
+#include "plugin_transport_wlan.h"
+#include "gnunet_common.h"
+#include "gnunet-transport-wlan-helper.h"
+#include "gnunet_crypto_lib.h"
-/**
- * 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.
+#include "wlan/radiotap-parser.h"
+/* radiotap-parser defines types like u8 that
+ * ieee80211_radiotap.h needs
*
- * Radiotap header length:
- * You can find the CPU-endian total radiotap header length in
- * iterator->max_length after executing ieee80211_radiotap_iterator_init()
- * successfully.
+ * we use our local copy of ieee80211_radiotap.h
*
- * Example code:
- * See Documentation/networking/radiotap-headers.txt
+ * - 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"
-int ieee80211_radiotap_iterator_init(
- struct ieee80211_radiotap_iterator *iterator,
- struct ieee80211_radiotap_header *radiotap_header,
- int max_length)
-{
- /* 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<<IEEE80211_RADIOTAP_EXT))) {
- while (le32_to_cpu(*((u32 *)iterator->arg)) &
- (1<<IEEE80211_RADIOTAP_EXT)) {
- iterator->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
- */
- }
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_FULL 803
- /* we are all initialized happily */
+#include "wlan/loopback_helper.h"
- return 0;
-}
+#define DEBUG 1
+#define MAC_ADDR_SIZE 6
-/**
- * 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.
- */
-
-int ieee80211_radiotap_iterator_next(
- struct ieee80211_radiotap_iterator *iterator)
+struct Hardware_Infos
{
- /*
- * 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.
- */
+ struct sendbuf write_pout;
+ int fd_raw;
+ int arptype_in;
- pad = (((ulong)iterator->arg) -
- ((ulong)iterator->rtheader)) &
- ((rt_sizes[iterator->arg_index] >> 4) - 1);
+ /**
+ * Name of the interface, not necessarily 0-terminated (!).
+ */
+ char iface[IFNAMSIZ];
+ unsigned char pl_mac[MAC_ADDR_SIZE];
+};
- if (pad)
- iterator->arg_index +=
- (rt_sizes[iterator->arg_index] >> 4) - pad;
+// FIXME: inline?
+int getChannelFromFrequency(int frequency);
- /*
- * 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.
- */
+// FIXME: make nice...
+static unsigned long
+calc_crc_osdep(unsigned char * buf, int len)
+{
+ unsigned long crc = 0xFFFFFFFF;
- 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;
- }
+ for (; len > 0; len--, buf++)
+ crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
- /* we don't know how to handle any more args, we're done */
- return -ENOENT;
+ return (~crc);
}
+/* CRC checksum verification routine */
-
-int
-main(int argc, char *argv[])
+// FIXME: make nice...
+static int
+check_crc_buf_osdep(unsigned char *buf, int len)
{
- 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 <andy@warmcat.com> 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;
- }
- }
+ unsigned long crc;
- if (optind >= argc)
- usage();
+ if (0 > len)
+ return 0;
+ 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]);
+}
- // 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;
-
- 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);
+// FIXME: make nice...
+static int
+linux_get_channel(struct Hardware_Infos *dev)
+{
+ struct iwreq wrq;
+ int fd, frequency;
+ int chan = 0;
- memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
+ memset(&wrq, 0, sizeof(struct iwreq));
- while (!fBrokenSocket) {
- u8 * pu8 = u8aSendBuffer;
- struct pcap_pkthdr * ppcapPacketHeader = NULL;
- struct ieee80211_radiotap_iterator rti;
- PENUMBRA_RADIOTAP_DATA prd;
- u8 * pu8Payload = u8aSendBuffer;
- int n, nRate;
+ strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
- // receive
+ fd = dev->fd_raw;
+ if (0 > ioctl(fd, SIOCGIWFREQ, &wrq))
+ return (-1);
- retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
- (const u_char**)&pu8Payload);
+ frequency = wrq.u.freq.m;
+ if (100000000 < frequency )
+ frequency /= 100000;
+ else if (1000000 < frequency )
+ frequency /= 1000;
- if (retval < 0) {
- fBrokenSocket = 1;
- continue;
- }
+ if (1000 < frequency)
+ chan = getChannelFromFrequency(frequency);
+ else
+ chan = frequency;
- if (retval != 1)
- goto do_tx;
+ return chan;
+}
- u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
- printf("rtap: ");
- Dump(pu8Payload, u16HeaderLen);
+// FIXME: make nice...
+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;
+
+ 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);
+ }
+
+ if (n < 8 || n >= caplen)
+ return (0);
+ }
+ break;
+
+ case ARPHRD_IEEE80211_FULL:
+ {
+ 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
+ */
+
+ while (ieee80211_radiotap_iterator_next(&iterator) >= 0)
+ {
+
+ 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;
+ }
+ }
+ 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;
+}
- if (ppcapPacketHeader->len <
- (u16HeaderLen + n80211HeaderLength))
- continue;
- bytes = ppcapPacketHeader->len -
- (u16HeaderLen + n80211HeaderLength);
- if (bytes < 0)
- continue;
+/**
+ * @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,
+ "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;
+}
- if (ieee80211_radiotap_iterator_init(&rti,
- (struct ieee80211_radiotap_header *)pu8Payload,
- bytes) < 0)
- continue;
+/**
+ * @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;
+}
- while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
- switch (rti.this_arg_index) {
- case IEEE80211_RADIOTAP_RATE:
- prd.m_nRate = (*rti.this_arg);
- break;
+/**
+ * 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;
+}
- 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;
+/**
+ * function to set the wlan header to make attacks more difficult
+ * @param buf buffer 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);
- case IEEE80211_RADIOTAP_FLAGS:
- prd.m_nRadiotapFlags = *rti.this_arg;
- break;
+}
- }
- }
+struct RadioTapheader
+{
+ struct ieee80211_radiotap_header header;
+ u8 rate;
+ u8 pad1;
+ u16 txflags;
+};
- pu8Payload += u16HeaderLen + n80211HeaderLength;
+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.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: mailformed 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 (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
- bytes -= 4;
+#if 0
+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);
- 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);
+}
+#endif
- Dump(pu8Payload, bytes);
- do_tx:
+/**
+ * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
+ * @param buffer pointer to buffer for the message
+ * @param mac pointer to the mac address
+ * @return number of bytes written
+ */
+// FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file)
+static int
+send_mac_to_plugin(char * buffer, uint8_t * mac)
+{
+ struct Wlan_Helper_Control_Message macmsg;
- // transmit
+ macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message));
+ macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
+ memcpy(macmsg.mac.mac, mac, sizeof(struct MacAddress));
+ memcpy(buffer, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
+ return sizeof(struct Wlan_Helper_Control_Message);
+}
- 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);
+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) )
+ {
+ 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)
+ {
+ 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;
+ }
+ }
+
+ if (FD_ISSET(dev.fd_raw, &wfds))
+ {
+ 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 (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 (FD_ISSET(dev.fd_raw, &rfds))
+ {
+ 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);
+ }
+ }
+
+ }
+ /* Error handling, try to clean up a bit at least */
+ GNUNET_SERVER_mst_destroy(stdin_mst);
+ close (dev.fd_raw);
+ return 1;
+}
-
-
- return (0);
+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);
}