paragraph for gnunet devs that don't know how to use the web
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-wlan.c
index 649a6cf18575492b47827a3b0818c99a86e4cc85..59a2d8b567b207532fba5d63f273bf22855f378a 100644 (file)
@@ -1,23 +1,21 @@
 /*
    This file is part of GNUnet.
-   (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+   Copyright (C) 2010, 2011, 2012 GNUnet e.V.
    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
-   Copyright (C) 2009 Thomas d'Otreppe
+   Copyright Copyright (C) 2009 Thomas d'Otreppe
 
-   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 free software: you can redistribute it and/or modify it
+   under the terms of the GNU Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   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.
+   Affero General Public License for more details.
+  
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /**
  * @file src/transport/gnunet-helper-transport-wlan.c
  * parts taken from aircrack-ng, parts changend.
  */
 #include "gnunet_config.h"
+#define SOCKTYPE int
+#define FDTYPE int
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include "plugin_transport_wlan.h"
 
 /**
- * Packet format type for the messages we receive from 
+ * Packet format type for the messages we receive from
+ * the kernel.  This is for Ethernet 10Mbps format (no
+ * performance information included).
+ */
+#define ARPHRD_ETHER        1
+
+
+/**
+ * Packet format type for the messages we receive from
  * the kernel.  This is for plain messages (with no
  * performance information included).
  */
 #define ARPHRD_IEEE80211        801
 
+
 /**
- * Packet format type for the messages we receive from 
+ * Packet format type for the messages we receive from
  * the kernel.  This is for the PRISM format.
  */
 #define ARPHRD_IEEE80211_PRISM  802
 
 /**
- * Packet format type for the messages we receive from 
+ * Packet format type for the messages we receive from
  * the kernel.  This is for messages with a
  * 'struct Ieee80211RadiotapHeader' (see below).
  */
  * Drivers appear to use a 64bit counter to hold mactime internal
  * the then fill the prism header with the lower 32 bits
  */
-#define PRISM_DID_MACTIME 0x2041 
+#define PRISM_DID_MACTIME 0x2041
 
 /**
  * Channel element
  */
-#define PRISM_DID_CHANNEL 0x3041 
+#define PRISM_DID_CHANNEL 0x3041
 
 /**
  * Signal element.  Should be the signal strength in dbm, some people
  * suggest that instead "100 - (strength in dbm)" is used (to make this
  * a positive integer).
  */
-#define PRISM_DID_SIGNAL 0x6041 
+#define PRISM_DID_SIGNAL 0x6041
 
 /**
  * Noise element
  */
-#define PRISM_DID_NOISE 0x7041 
+#define PRISM_DID_NOISE 0x7041
 
 /**
  * Rate element, in units/multiples of 500Khz
  */
-#define PRISM_DID_RATE 0x8041 
+#define PRISM_DID_RATE 0x8041
 
 
 /**
  * Value is set (supplied)
  */
-#define PRISM_STATUS_OK 0 
+#define PRISM_STATUS_OK 0
 
 /**
  * Value not supplied.
@@ -229,24 +238,24 @@ struct PrismValue
    * This has a different ID for each parameter, see
    * PRISM_DID_* constants.
    */
-  uint32_t did; 
-  
+  uint32_t did;
+
   /**
    * See PRISM_STATUS_*-constants.  Note that they are unusual: 0 = set;  1 = not set
    */
-  uint16_t status; 
-  
+  uint16_t status;
+
   /**
    * length of data (which is always a uint32_t, but presumably this can be used
    * to specify that fewer bytes are used (with values in 'len' from 0-4).  We
    * ignore this field.
    */
-  uint16_t len; 
+  uint16_t len;
 
   /**
    * The data value
    */
-  uint32_t data; 
+  uint32_t data;
 
 } __attribute__ ((packed));
 
@@ -260,11 +269,11 @@ struct PrismHeader
    * We expect this to be a PRISM_MSGCODE_*.
    */
   uint32_t msgcode;
-  
+
   /**
    * The length of the entire header.
    */
-  uint32_t msglen;     
+  uint32_t msglen;
 
   /**
    * Name of the device that captured the packet.
@@ -391,7 +400,7 @@ enum RadiotapType
    */
   IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
 
-  /** 
+  /**
    * IEEE80211_RADIOTAP_ANTENNA           uint8_t           antenna index
    *
    *      Unitless indication of the Rx/Tx antenna for this packet.
@@ -422,10 +431,10 @@ enum RadiotapType
    */
   IEEE80211_RADIOTAP_RX_FLAGS = 14,
 
-  /** 
+  /**
    * IEEE80211_RADIOTAP_TX_FLAGS          __le16       bitmap
    *
-   *     Properties of transmitted frames. See flags defined below.  
+   *     Properties of transmitted frames. See flags defined below.
    */
   IEEE80211_RADIOTAP_TX_FLAGS = 15,
 
@@ -451,7 +460,7 @@ enum RadiotapType
 };
 
 /**
- * Bitmask indicating an extension of the bitmask is used. 
+ * Bitmask indicating an extension of the bitmask is used.
  * (Mask corresponding to IEEE80211_RADIOTAP_EXT).
  */
 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT)
@@ -476,7 +485,7 @@ enum RadiotapType
  *
  * Frame was sent/received with short preamble
  */
-#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02  
+#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02
 
 /**
  * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
@@ -486,7 +495,7 @@ enum RadiotapType
  *
  * Frame was sent/received with WEP encryption
  */
-#define        IEEE80211_RADIOTAP_F_WEP        0x04 
+#define        IEEE80211_RADIOTAP_F_WEP        0x04
 
 /**
  * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
@@ -496,7 +505,7 @@ enum RadiotapType
  *
  * Frame was sent/received with fragmentation
  */
-#define        IEEE80211_RADIOTAP_F_FRAG       0x08 
+#define        IEEE80211_RADIOTAP_F_FRAG       0x08
 
 /**
  * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
@@ -506,7 +515,7 @@ enum RadiotapType
  *
  * Frame includes FCS (CRC at the end that needs to be removeD).
  */
-#define        IEEE80211_RADIOTAP_F_FCS        0x10    
+#define        IEEE80211_RADIOTAP_F_FCS        0x10
 
 /**
  * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
@@ -517,32 +526,32 @@ enum RadiotapType
  * Frame has padding between 802.11 header and payload
  * (to 32-bit boundary)
  */
-#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20    
+#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20
 
 
 /**
  * For IEEE80211_RADIOTAP_RX_FLAGS:
  * frame failed crc check
  */
-#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001  
+#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
 
 /**
  * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
  * failed due to excessive retries
  */
-#define IEEE80211_RADIOTAP_F_TX_FAIL   0x0001  
+#define IEEE80211_RADIOTAP_F_TX_FAIL   0x0001
 
 /**
  * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
  * used cts 'protection'
  */
-#define IEEE80211_RADIOTAP_F_TX_CTS    0x0002  
+#define IEEE80211_RADIOTAP_F_TX_CTS    0x0002
 
 /**
  * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
- * used rts/cts handshake 
+ * used rts/cts handshake
  */
-#define IEEE80211_RADIOTAP_F_TX_RTS    0x0004  
+#define IEEE80211_RADIOTAP_F_TX_RTS    0x0004
 
 /**
  * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
@@ -552,7 +561,7 @@ enum RadiotapType
 
 /**
  * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
- * sequence number handled by userspace 
+ * sequence number handled by userspace
  */
 #define IEEE80211_RADIOTAP_F_TX_NOSEQ  0x0010
 
@@ -580,7 +589,7 @@ struct Ieee80211RadiotapHeader
   uint8_t it_version;
 
   /**
-   * Padding.  Set to 0.  
+   * Padding.  Set to 0.
    */
   uint8_t it_pad;
 
@@ -600,7 +609,7 @@ struct Ieee80211RadiotapHeader
 
 
 /**
- * Format of the header we need to prepend to messages to be sent to the 
+ * Format of the header we need to prepend to messages to be sent to the
  * Kernel.
  */
 struct RadiotapTransmissionHeader
@@ -741,7 +750,7 @@ struct SendBuffer
    * destination?  Always smaller than 'size'.
    */
   size_t pos;
-  
+
   /**
    * Buffered data; twice the maximum allowed message size as we add some
    * headers.
@@ -783,7 +792,7 @@ static struct SendBuffer write_std;
  * @param cls closure
  * @param message the actual message
  */
-typedef void (*MessageTokenizerCallback) (void *cls, 
+typedef void (*MessageTokenizerCallback) (void *cls,
                                          const struct
                                          GNUNET_MessageHeader *
                                          message);
@@ -899,7 +908,7 @@ do_align:
       delta =
           GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
                       (mst->pos - mst->off), size);
-      memcpy (&ibuf[mst->pos], buf, delta);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
       mst->pos += delta;
       buf += delta;
       size -= delta;
@@ -938,7 +947,7 @@ do_align:
     if (mst->pos - mst->off < want)
     {
       delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
-      memcpy (&ibuf[mst->pos], buf, delta);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
       mst->pos += delta;
       buf += delta;
       size -= delta;
@@ -1005,7 +1014,7 @@ do_align:
               "Assertion failed\n");
       exit (1);
     }
-    memcpy (&ibuf[mst->pos], buf, size);
+    GNUNET_memcpy (&ibuf[mst->pos], buf, size);
     mst->pos += size;
   }
   return ret;
@@ -1048,7 +1057,7 @@ mst_destroy (struct MessageStreamTokenizer *mst)
  */
 static int
 ieee80211_radiotap_iterator_init (struct Ieee80211RadiotapHeaderIterator *iterator,
-                                  const struct Ieee80211RadiotapHeader *radiotap_header, 
+                                  const struct Ieee80211RadiotapHeader *radiotap_header,
                                  size_t max_length)
 {
   if ( (iterator == NULL) ||
@@ -1193,26 +1202,26 @@ ieee80211_radiotap_iterator_next (struct Ieee80211RadiotapHeaderIterator *iterat
        /* need padding (by 'wanted_alignment - unalignment') */
        iterator->arg_index += wanted_alignment - unalignment;
       }
-      
+
       /*
        * 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;
 
       /* internally move on the size of this arg (using lower nybble from
-        the table) */ 
+        the table) */
       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 ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > iterator->max_length)
-       return -1;      
+       return -1;
     }
 
     /* Now, move on to next bit / next entry */
@@ -1234,7 +1243,7 @@ ieee80211_radiotap_iterator_next (struct Ieee80211RadiotapHeaderIterator *iterat
       }
     }
     else
-    {                           
+    {
       /* just try the next bit (while loop will move on) */
       iterator->bitmap_shifter >>= 1;
     }
@@ -1353,7 +1362,7 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len)
   if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
       ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
     return 0;
-  return 1;     
+  return 1;
 }
 
 
@@ -1420,7 +1429,7 @@ linux_get_channel (const struct HardwareInfos *dev)
  * @return number of bytes written to 'buf'
  */
 static ssize_t
-linux_read (struct HardwareInfos *dev, 
+linux_read (struct HardwareInfos *dev,
            unsigned char *buf, size_t buf_size,
             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
 {
@@ -1441,7 +1450,7 @@ linux_read (struct HardwareInfos *dev,
     return -1;
   }
 
-  memset (ri, 0, sizeof (*ri)); 
+  memset (ri, 0, sizeof (*ri));
   switch (dev->arptype_in)
   {
   case ARPHRD_IEEE80211_PRISM:
@@ -1464,7 +1473,7 @@ linux_read (struct HardwareInfos *dev,
        while (left > sizeof (struct PrismValue))
        {
          left -= sizeof (struct PrismValue);
-         memcpy (&pv, pos, sizeof (struct PrismValue));
+         GNUNET_memcpy (&pv, pos, sizeof (struct PrismValue));
          pos += sizeof (struct PrismValue);
 
          switch (pv.did)
@@ -1473,7 +1482,7 @@ linux_read (struct HardwareInfos *dev,
            if (PRISM_STATUS_OK == pv.status)
            {
              ri->ri_noise = pv.data;
-             got_noise = 1;
+             /* got_noise = 1; */
            }
            break;
          case PRISM_DID_RATE:
@@ -1495,12 +1504,12 @@ linux_read (struct HardwareInfos *dev,
            if (PRISM_STATUS_OK == pv.status)
            {
              ri->ri_power = pv.data;
-             got_signal = 1;
+             /* got_signal = 1; */
            }
            break;
          }
        }
-      } 
+      }
       if ( (n < 8) || (n >= caplen) )
        return 0; /* invalid format */
     }
@@ -1529,7 +1538,7 @@ linux_read (struct HardwareInfos *dev,
          if (!got_signal)
          {
            ri->ri_power = * ((int8_t*) iterator.this_arg);
-           got_signal = 1;       
+           got_signal = 1;     
          }
          break;
        case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
@@ -1583,11 +1592,20 @@ linux_read (struct HardwareInfos *dev,
          break;
        } /* end of 'switch' */
       } /* end of the 'while' loop */
-    }       
+    }
     break;
   case ARPHRD_IEEE80211:
     n = 0; /* no header */
     break;
+  case ARPHRD_ETHER:
+    {
+      if (sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
+       return 0; /* invalid */
+      GNUNET_memcpy (&buf[sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)],
+             tmpbuf + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame),
+             caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4 /* 4 byte FCS */);
+      return caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
+    }  
   default:
     errno = ENOTSUP; /* unsupported format */
     return -1;
@@ -1597,8 +1615,8 @@ linux_read (struct HardwareInfos *dev,
     ri->ri_channel = linux_get_channel (dev);
 
   /* detect CRC32 at the end, even if the flag wasn't set and remove it */
-  if ( (0 == fcs_removed) && 
-       (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) )  
+  if ( (0 == fcs_removed) &&
+       (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) )
   {
     /* NOTE: this heuristic can of course fail if there happens to
        be a matching checksum at the end. Would be good to have
@@ -1606,7 +1624,7 @@ linux_read (struct HardwareInfos *dev,
     caplen -= sizeof (uint32_t);
   }
   /* copy payload to target buffer */
-  memcpy (buf, tmpbuf + n, caplen);
+  GNUNET_memcpy (buf, tmpbuf + n, caplen);
   return caplen;
 }
 
@@ -1651,6 +1669,16 @@ open_device_raw (struct HardwareInfos *dev)
              IFNAMSIZ, dev->iface, strerror (errno));
     return 1;
   }
+  if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
+       (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
+       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
+       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) )
+  {
+    fprintf (stderr, "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
+             IFNAMSIZ, dev->iface,
+            ifr.ifr_hwaddr.sa_family);
+    return 1;
+  }
 
   /* lookup iw mode */
   memset (&wrq, 0, sizeof (struct iwreq));
@@ -1662,13 +1690,12 @@ open_device_raw (struct HardwareInfos *dev)
     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))
+  if ( (wrq.u.mode != IW_MODE_MONITOR) &&
+       (wrq.u.mode != IW_MODE_ADHOC) ) 
   {
-    fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
-             IFNAMSIZ, dev->iface);
+    fprintf (stderr, "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
+             IFNAMSIZ, dev->iface,
+            wrq.u.mode);
     return 1;
   }
 
@@ -1702,9 +1729,10 @@ open_device_raw (struct HardwareInfos *dev)
     return 1;
   }
 
-  memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
+  GNUNET_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) &&
+  if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
+      (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
   {
@@ -1721,9 +1749,9 @@ open_device_raw (struct HardwareInfos *dev)
       setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
                   sizeof (mr)))
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "Failed to enable promiscuous mode on interface `%.*s'\n",
-             IFNAMSIZ, 
+             IFNAMSIZ,
             dev->iface);
     return 1;
   }
@@ -1745,13 +1773,13 @@ test_wlan_interface (const char *iface)
   struct stat sbuf;
   int ret;
 
-  ret = snprintf (strbuf, sizeof (strbuf), 
+  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", 
+    fprintf (stderr,
+            "Did not find 802.11 interface `%s'. Exiting.\n",
             iface);
     exit (1);
   }
@@ -1770,6 +1798,12 @@ static int
 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
           const struct HardwareInfos *dev)
 {
+  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
+
+  if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
+       (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
+    return 0; /* some drivers set no Macs, then assume it is all for us! */
+
   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
     return 1; /* not a GNUnet ad-hoc package */
   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
@@ -1811,11 +1845,12 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
   size_t sendsize;
   struct RadiotapTransmissionHeader rtheader;
+  struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
 
   sendsize = ntohs (hdr->size);
   if ( (sendsize <
        sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
-       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
+       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
   {
     fprintf (stderr, "Received malformed message\n");
     exit (1);
@@ -1827,21 +1862,41 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
     exit (1);
   }
   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
-  rtheader.header.it_version = 0;
-  rtheader.header.it_pad = 0; 
-  rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
-  rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK);
-  rtheader.rate = header->rate; 
-  rtheader.pad1 = 0;
-  rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
-  memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
-  memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize);
-  wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
-
-  /* payload contains MAC address, but we don't trust it, so we'll
-   * overwrite it with OUR MAC address to prevent mischief */
-  mac_set (wlanheader, dev);
-  write_pout.size = sendsize + sizeof (rtheader);
+  switch (dev->arptype_in)
+  {
+  case ARPHRD_IEEE80211_PRISM:
+  case ARPHRD_IEEE80211_FULL:
+  case ARPHRD_IEEE80211:
+    rtheader.header.it_version = 0;
+    rtheader.header.it_pad = 0;
+    rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
+    rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK);
+    rtheader.rate = header->rate;
+    rtheader.pad1 = 0;
+    rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
+    GNUNET_memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
+    GNUNET_memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize);
+    wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
+
+    /* payload contains MAC address, but we don't trust it, so we'll
+     * overwrite it with OUR MAC address to prevent mischief */
+    mac_set (wlanheader, dev);
+    write_pout.size = sendsize + sizeof (rtheader);
+    break;
+  case ARPHRD_ETHER:
+    etheader.dst = header->frame.addr1;
+    /* etheader.src = header->frame.addr2; --- untrusted input */
+    etheader.src = dev->pl_mac;
+    etheader.type = htons (ETH_P_IP);
+    GNUNET_memcpy (write_pout.buf, &etheader, sizeof (etheader));
+    GNUNET_memcpy (&write_pout.buf[sizeof (etheader)], &header[1], sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
+    write_pout.size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame) + sizeof (etheader);
+    break;
+  default:
+    fprintf (stderr,
+            "Unsupported ARPTYPE!\n");
+    break;
+  }
 }
 
 
@@ -1868,20 +1923,26 @@ main (int argc, char *argv[])
   int raw_eno;
 
   /* assert privs so we can modify the firewall rules! */
-  uid = getuid ();
-#ifdef HAVE_SETRESUID
-  if (0 != setresuid (uid, 0, 0))
   {
-    fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
-    return 254;
-  }
+#ifdef HAVE_SETRESUID
+    uid_t uid = getuid ();
+
+    if (0 != setresuid (uid, 0, 0))
+    {
+      fprintf (stderr,
+              "Failed to setresuid to root: %s\n", 
+              strerror (errno));
+      return 254;
+    }
 #else
-  if (0 != seteuid (0)) 
-  {
-    fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
-    return 254;
-  }
+    if (0 != seteuid (0))
+    {
+      fprintf (stderr, 
+              "Failed to seteuid back to root: %s\n", strerror (errno));
+      return 254;
+    }
 #endif
+  }
 
   /* make use of SGID capabilities on POSIX */
   memset (&dev, 0, sizeof (dev));
@@ -1951,12 +2012,12 @@ main (int argc, char *argv[])
 
     macmsg.hdr.size = htons (sizeof (macmsg));
     macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
-    memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
-    memcpy (write_std.buf, &macmsg, sizeof (macmsg));
+    GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+    GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
     write_std.size = sizeof (macmsg);
-  }  
+  }
 
-  stdin_mst = mst_create (&stdin_send_hw, &dev);  
+  stdin_mst = mst_create (&stdin_send_hw, &dev);
   stdin_open = 1;
   while (1)
   {
@@ -2013,7 +2074,7 @@ main (int argc, char *argv[])
     if (FD_ISSET (dev.fd_raw, &wfds))
     {
       ssize_t ret =
-       write (dev.fd_raw, write_pout.buf + write_std.pos, 
+       write (dev.fd_raw, write_pout.buf + write_pout.pos,
               write_pout.size - write_pout.pos);
       if (0 > ret)
       {
@@ -2039,7 +2100,7 @@ main (int argc, char *argv[])
 
     if (FD_ISSET (STDIN_FILENO, &rfds))
     {
-      ssize_t ret = 
+      ssize_t ret =
        read (STDIN_FILENO, readbuf, sizeof (readbuf));
       if (0 > ret)
       {
@@ -2062,9 +2123,9 @@ main (int argc, char *argv[])
       rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
       ret =
           linux_read (&dev, (unsigned char *) &rrm->frame,
-                      sizeof (write_std.buf) 
-                     - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
-                     + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
+                      sizeof (write_std.buf)
+                     - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+                     + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
                      rrm);
       if (0 > ret)
       {
@@ -2073,8 +2134,8 @@ main (int argc, char *argv[])
       }
       if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
       {
-        write_std.size = ret 
-         + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
+        write_std.size = ret
+         + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
          - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
         rrm->header.size = htons (write_std.size);
         rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);