msg
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-wlan.c
index 03862cc1c14887b0abd8d79864c4563776a55886..3ad4d64c424dbbf6433b4015d971e47328037e0e 100644 (file)
@@ -1,6 +1,6 @@
 /*
    This file is part of GNUnet.
-   (C) 2010, 2011 Christian Grothoff (and other contributing authors)
+   (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
    Copyright (C) 2009 Thomas d'Otreppe
 
 */
 /**
  * @file src/transport/gnunet-helper-transport-wlan.c
- * @brief wlan layer two server; must run as root (SUID will do)
+ * @brief mediator between the wlan interface and gnunet; must run as root (SUID will do)
  *        This code will work under GNU/Linux only.
  * @author David Brodski
+ * @author Christian Grothoff
  *
- * This program serves as the mediator between the wlan interface and
- * gnunet
+ * This program will allow receiving and sending traffic from the WLAN
+ * interface.  It will force traffic to be in 'ad-hoc' mode, use the
+ * proper MAC address of the WLAN interface and use a GNUnet-specific
+ * SSID (and a GNUnet-specific SNAP header).  It only takes a single
+ * argument, which is the name of the WLAN interface to use.  The
+ * program detects if the interface is not a WLAN interface and exits
+ * with an error in that case.
+ *
+ * Once initialized, the program will first send a 'struct
+ * GNUNET_TRANSPORT_WLAN_HelperControlMessage' to 'stdout'.  That
+ * message contains the MAC address of the WLAN interface.  It will
+ * then read messages from the WLAN interface and send them together
+ * with performance information as 'struct
+ * GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage' messages to 'stdout'.
+ * Furthermore, it will read a stream of messages from 'stdin' that
+ * have the format from 'struct
+ * GNUNET_TRANSPORT_WLAN_RadiotapSendMessage'.  Those messages will
+ * then be sent via the WLAN interface; however, the sender MAC
+ * address will be forced to be the correct address from our WLAN
+ * card.  If 'stdin' closes, receiving from the WLAN interface will
+ * continue.  If 'stdout' causes a SIGPIPE, the process dies from the
+ * signal.  Errors cause an error message to be reported to 'stderr',
+ * in most cases the process also exits (with status code '1').  The
+ * program never terminates normally; it is safe to kill the
+ * process with SIGTERM or SIGKILL at any time.
+ *
+ * Since it uses RAW sockets, the binary must be installed SUID or run
+ * as 'root'.  In order to keep the security risk of the resulting
+ * SUID binary minimal, the program ONLY opens the RAW socket with
+ * root privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against any
+ * shared libraries (except libc) and is strictly minimal (except for
+ * checking for errors).  The following list of people have reviewed
+ * this code and considered it safe since the last modification (if
+ * you reviewed it, please have your name added to the list):
+ *
+ * - Christian Grothoff (Apr 3rd 2012)
  */
 
 /*-
  * Modifications to fit into the linux IEEE 802.11 stack,
  * Mike Kershaw (dragorn@kismetwireless.net)
  */
-
-/**
+/*
  * parts taken from aircrack-ng, parts changend.
  */
-#define _GNU_SOURCE
+#include "gnunet_config.h"
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include "gnunet_protocols.h"
 #include "plugin_transport_wlan.h"
 
+/**
+ * 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 
+ * the kernel.  This is for the PRISM format.
+ */
 #define ARPHRD_IEEE80211_PRISM  802
-#define ARPHRD_IEEE80211_FULL   803
 
 /**
- * size of 802.11 address
+ * Packet format type for the messages we receive from 
+ * the kernel.  This is for messages with a
+ * 'struct Ieee80211RadiotapHeader' (see below).
  */
-#define IEEE80211_ADDR_LEN      6
+#define ARPHRD_IEEE80211_FULL   803
+
 
 /**
- * Maximum size of a message allowed in either direction.
+ * Maximum size of a message allowed in either direction
+ * (used for our receive and sent buffers).
  */
 #define MAXLINE 4096
 
 
-#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
 
+/* ********* structure of messages of type ARPHRD_IEEE80211_PRISM *********** */
 
-/* Name                                 Data type    Units
- * ----                                 ---------    -----
- *
- * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
- *
- *      Value in microseconds of the MAC's 64-bit 802.11 Time
- *      Synchronization Function timer when the first bit of the
- *      MPDU arrived at the MAC. For received frames, only.
- *
- * IEEE80211_RADIOTAP_CHANNEL           2 x __le16   MHz, bitmap
- *
- *      Tx/Rx frequency in MHz, followed by flags (see below).
- *
- * IEEE80211_RADIOTAP_FHSS              __le16       see below
- *
- *      For frequency-hopping radios, the hop set (first byte)
- *      and pattern (second byte).
- *
- * IEEE80211_RADIOTAP_RATE              uint8_t           500kb/s
- *
- *      Tx/Rx data rate
- *
- * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      RF signal power at the antenna, decibel difference from
- *      one milliwatt.
- *
- * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      RF noise power at the antenna, decibel difference from one
- *      milliwatt.
- *
- * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t           decibel (dB)
- *
- *      RF signal power at the antenna, decibel difference from an
- *      arbitrary, fixed reference.
- *
- * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t           decibel (dB)
- *
- *      RF noise power at the antenna, decibel difference from an
- *      arbitrary, fixed reference point.
- *
- * IEEE80211_RADIOTAP_LOCK_QUALITY      __le16       unitless
- *
- *      Quality of Barker code lock. Unitless. Monotonically
- *      nondecreasing with "better" lock strength. Called "Signal
- *      Quality" in datasheets.  (Is there a standard way to measure
- *      this?)
- *
- * IEEE80211_RADIOTAP_TX_ATTENUATION    __le16       unitless
- *
- *      Transmit power expressed as unitless distance from max
- *      power set at factory calibration.  0 is max power.
- *      Monotonically nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16       decibels (dB)
- *
- *      Transmit power expressed as decibel distance from max power
- *      set at factory calibration.  0 is max power.  Monotonically
- *      nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
- *                                                   one milliwatt (dBm)
- *
- *      Transmit power expressed as dBm (decibels from a 1 milliwatt
- *      reference). This is the absolute power level measured at
- *      the antenna port.
- *
- * IEEE80211_RADIOTAP_FLAGS             uint8_t           bitmap
- *
- *      Properties of transmitted and received frames. See flags
- *      defined below.
- *
- * IEEE80211_RADIOTAP_ANTENNA           uint8_t           antenna index
- *
- *      Unitless indication of the Rx/Tx antenna for this packet.
- *      The first antenna is antenna 0.
- *
- * IEEE80211_RADIOTAP_RX_FLAGS          __le16       bitmap
- *
- *     Properties of received frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_TX_FLAGS          __le16       bitmap
- *
- *     Properties of transmitted frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_RTS_RETRIES       uint8_t           data
- *
- *     Number of rts retries a transmitted frame used.
- *
- * IEEE80211_RADIOTAP_DATA_RETRIES      uint8_t           data
- *
- *     Number of unicast retries a transmitted frame used.
- *
+/**
+ * Device name length in PRISM frames.
+ * (In the kernel, this is "WLAN_DEVNAMELEN_MAX")
+ */
+#define PRISM_DEVICE_NAME_LENGTH 16
+
+/**
+ * Monitor Frame (indicator that we have a 'struct PrismHeader').
+ */
+#define PRISM_MSGCODE_MONITOR 0x0041
+
+/**
+ * Mac time element.  In micro-seconds.
+ * 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 
+
+/**
+ * Channel element
+ */
+#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 
+
+/**
+ * Noise element
+ */
+#define PRISM_DID_NOISE 0x7041 
+
+/**
+ * Rate element, in units/multiples of 500Khz
+ */
+#define PRISM_DID_RATE 0x8041 
+
+
+/**
+ * Value is set (supplied)
+ */
+#define PRISM_STATUS_OK 0 
+
+/**
+ * Value not supplied.
+ */
+#define PRISM_STATUS_NO_VALUE 1
+
+
+/**
+ * Values in the 'struct PrismHeader'.  All in host byte order (!).
+ */
+struct PrismValue
+{
+  /**
+   * This has a different ID for each parameter, see
+   * PRISM_DID_* constants.
+   */
+  uint32_t did; 
+  
+  /**
+   * See PRISM_STATUS_*-constants.  Note that they are unusual: 0 = set;  1 = not set
+   */
+  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; 
+
+  /**
+   * The data value
+   */
+  uint32_t data; 
+
+} __attribute__ ((packed));
+
+
+/**
+ * Prism header format ('struct p80211msg' in Linux).  All in host byte order (!).
+ */
+struct PrismHeader
+{
+  /**
+   * We expect this to be a PRISM_MSGCODE_*.
+   */
+  uint32_t msgcode;
+  
+  /**
+   * The length of the entire header.
+   */
+  uint32_t msglen;     
+
+  /**
+   * Name of the device that captured the packet.
+   */
+  char devname[PRISM_DEVICE_NAME_LENGTH];
+
+  /* followed by 'struct PrismValue's.  Documentation suggests that these
+     are typically the hosttime, mactime, channel, rssi, sq, signal, noise,
+     rate, istx and frmlen values, but documentation is sparse.  So we
+     will use the 'did' fields to find out what we actually got. */
+
+} __attribute__ ((packed));
+
+
+/* ******  end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */
+
+/* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */
+
+/**
+ * Bits in the 'it_present' bitmask from the 'struct
+ * Ieee80211RadiotapHeader'.  For each value, we give the name, data
+ * type, unit and then a description below.  Note that the actual size
+ * of the extension can be bigger as arguments must be padded so that
+ * args of a given length must begin at a boundary of that length.
+ * However, note that compound args are allowed (eg, 2 x uint16_t for
+ * IEEE80211_RADIOTAP_CHANNEL) so total argument length is not a
+ * reliable indicator of alignment requirement.  See also
+ * 'man 9 ieee80211_radiotap'.
  */
 enum RadiotapType
 {
+
+  /**
+   * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
+   *
+   *      Value in microseconds of the MAC's 64-bit 802.11 Time
+   *      Synchronization Function timer when the first bit of the
+   *      MPDU arrived at the MAC. For received frames, only.
+   */
   IEEE80211_RADIOTAP_TSFT = 0,
+
+  /**
+   * IEEE80211_RADIOTAP_FLAGS             uint8_t           bitmap
+   *
+   *      Properties of transmitted and received frames. See flags
+   *      defined below.
+   */
   IEEE80211_RADIOTAP_FLAGS = 1,
+
+  /**
+   * IEEE80211_RADIOTAP_RATE              uint8_t           500kb/s
+   *
+   *      Tx/Rx data rate
+   */
   IEEE80211_RADIOTAP_RATE = 2,
+
+  /**
+   * IEEE80211_RADIOTAP_CHANNEL           2 x __le16   MHz, bitmap
+   *
+   *      Tx/Rx frequency in MHz, followed by flags (see below).
+   */
   IEEE80211_RADIOTAP_CHANNEL = 3,
+  /**
+   * IEEE80211_RADIOTAP_FHSS              __le16       see below
+   *
+   *      For frequency-hopping radios, the hop set (first byte)
+   *      and pattern (second byte).
+   */
   IEEE80211_RADIOTAP_FHSS = 4,
+
+  /**
+   * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
+   *                                                   one milliwatt (dBm)
+   *
+   *      RF signal power at the antenna, decibel difference from
+   *      one milliwatt.
+   */
   IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+
+  /**
+   * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
+   *                                                   one milliwatt (dBm)
+   *
+   *      RF noise power at the antenna, decibel difference from one
+   *      milliwatt.
+   */
   IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+
+  /**
+   * IEEE80211_RADIOTAP_LOCK_QUALITY      __le16       unitless
+   *
+   *      Quality of Barker code lock. Unitless. Monotonically
+   *      nondecreasing with "better" lock strength. Called "Signal
+   *      Quality" in datasheets.  (Is there a standard way to measure
+   *      this?)
+   */
   IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+
+  /**
+   * IEEE80211_RADIOTAP_TX_ATTENUATION    __le16       unitless
+   *
+   *      Transmit power expressed as unitless distance from max
+   *      power set at factory calibration.  0 is max power.
+   *      Monotonically nondecreasing with lower power levels.
+   */
   IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+
+  /**
+   * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16       decibels (dB)
+   *
+   *      Transmit power expressed as decibel distance from max power
+   *      set at factory calibration.  0 is max power.  Monotonically
+   *      nondecreasing with lower power levels.
+   */
   IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+
+  /**
+   * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
+   *                                                   one milliwatt (dBm)
+   *
+   *      Transmit power expressed as dBm (decibels from a 1 milliwatt
+   *      reference). This is the absolute power level measured at
+   *      the antenna port.
+   */
   IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+
+  /** 
+   * IEEE80211_RADIOTAP_ANTENNA           uint8_t           antenna index
+   *
+   *      Unitless indication of the Rx/Tx antenna for this packet.
+   *      The first antenna is antenna 0.
+   */
   IEEE80211_RADIOTAP_ANTENNA = 11,
+
+  /**
+   * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t           decibel (dB)
+   *
+   *      RF signal power at the antenna, decibel difference from an
+   *      arbitrary, fixed reference.
+   */
   IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+
+  /**
+   * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t           decibel (dB)
+   *
+   *      RF noise power at the antenna, decibel difference from an
+   *      arbitrary, fixed reference point.
+   */
   IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+
+  /**
+   * IEEE80211_RADIOTAP_RX_FLAGS          __le16       bitmap
+   *
+   *     Properties of received frames. See flags defined below.
+   */
   IEEE80211_RADIOTAP_RX_FLAGS = 14,
+
+  /** 
+   * IEEE80211_RADIOTAP_TX_FLAGS          __le16       bitmap
+   *
+   *     Properties of transmitted frames. See flags defined below.  
+   */
   IEEE80211_RADIOTAP_TX_FLAGS = 15,
+
+  /**
+   * IEEE80211_RADIOTAP_RTS_RETRIES       uint8_t           data
+   *
+   *     Number of rts retries a transmitted frame used.
+   */
   IEEE80211_RADIOTAP_RTS_RETRIES = 16,
+
+  /**
+   * IEEE80211_RADIOTAP_DATA_RETRIES      uint8_t           data
+   *
+   *     Number of unicast retries a transmitted frame used.
+   */
   IEEE80211_RADIOTAP_DATA_RETRIES = 17,
+
+  /**
+   * Extension bit, used to indicate that more bits are needed for
+   * the bitmask.
+   */
   IEEE80211_RADIOTAP_EXT = 31
 };
 
-/* For IEEE80211_RADIOTAP_FLAGS */
-#define        IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
-                                                 * during CFP
-                                                 */
-#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
-                                                 * with short
-                                                 * preamble
-                                                 */
-#define        IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
-                                                 * with WEP encryption
-                                                 */
-#define        IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
-                                                 * with fragmentation
-                                                 */
-#define        IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
-#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
-                                                 * 802.11 header and payload
-                                                 * (to 32-bit boundary)
-                                                 */
-/* For IEEE80211_RADIOTAP_RX_FLAGS */
-#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001  /* frame failed crc check */
-
-/* For IEEE80211_RADIOTAP_TX_FLAGS */
-#define IEEE80211_RADIOTAP_F_TX_FAIL   0x0001  /* failed due to excessive
-                                                 * retries */
-#define IEEE80211_RADIOTAP_F_TX_CTS    0x0002  /* used cts 'protection' */
-#define IEEE80211_RADIOTAP_F_TX_RTS    0x0004  /* used rts/cts handshake */
-#define IEEE80211_RADIOTAP_F_TX_NOACK  0x0008  /* frame should not be ACKed */
-#define IEEE80211_RADIOTAP_F_TX_NOSEQ  0x0010  /* sequence number handled
-                                                 * by userspace */
+/**
+ * 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)
+
+
 
+/**
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
+ *
+ * Frame was sent/received during CFP (Contention Free Period)
+ */
+#define        IEEE80211_RADIOTAP_F_CFP        0x01
 
 /**
- * A generic radio capture format is desirable. There is one for
- * Linux, but it is neither rigidly defined (there were not even
- * units given for some fields) nor easily extensible.
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
  *
- * I suggest the following extensible radio capture format. It is
- * based on a bitmap indicating which fields are present.
+ * Frame was sent/received with short preamble
+ */
+#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02  
+
+/**
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
+ *
+ * Frame was sent/received with WEP encryption
+ */
+#define        IEEE80211_RADIOTAP_F_WEP        0x04 
+
+/**
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
+ *
+ * Frame was sent/received with fragmentation
+ */
+#define        IEEE80211_RADIOTAP_F_FRAG       0x08 
+
+/**
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
+ *
+ * Frame includes FCS (CRC at the end that needs to be removeD).
+ */
+#define        IEEE80211_RADIOTAP_F_FCS        0x10    
+
+/**
+ * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
+ * as part of a 'struct Ieee80211RadiotapHeader' extension
+ * if the IEEE80211_RADIOTAP_FLAGS bit is set in
+ * 'it_present').  The radiotap flags are an 8-bit field.
+ *
+ * Frame has padding between 802.11 header and payload
+ * (to 32-bit boundary)
+ */
+#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20    
+
+
+/**
+ * For IEEE80211_RADIOTAP_RX_FLAGS:
+ * frame failed crc check
+ */
+#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  
+
+/**
+ * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
+ * used cts 'protection'
+ */
+#define IEEE80211_RADIOTAP_F_TX_CTS    0x0002  
+
+/**
+ * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
+ * used rts/cts handshake 
+ */
+#define IEEE80211_RADIOTAP_F_TX_RTS    0x0004  
+
+/**
+ * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
+ * frame should not be ACKed
+ */
+#define IEEE80211_RADIOTAP_F_TX_NOACK  0x0008
+
+/**
+ * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
+ * sequence number handled by userspace 
+ */
+#define IEEE80211_RADIOTAP_F_TX_NOSEQ  0x0010
+
+
+/**
+ * Generic header for radiotap messages (receiving and sending).  A
+ * bit mask (it_present) determines which specific records follow.
  *
  * I am trying to describe precisely what the application programmer
  * should expect in the following, and for that reason I tell the
@@ -290,7 +580,7 @@ enum RadiotapType
  * The radio capture header precedes the 802.11 header.
  * All data in the header is little endian on all platforms.
  */
-struct ieee80211_radiotap_header
+struct Ieee80211RadiotapHeader
 {
   /**
    * Version 0. Only increases for drastic changes, introduction of
@@ -299,7 +589,7 @@ struct ieee80211_radiotap_header
   uint8_t it_version;
 
   /**
-   *
+   * Padding.  Set to 0.  
    */
   uint8_t it_pad;
 
@@ -317,150 +607,176 @@ struct ieee80211_radiotap_header
   uint32_t it_present;
 };
 
+
 /**
- *
+ * Format of the header we need to prepend to messages to be sent to the 
+ * Kernel.
  */
-struct RadioTapheader
+struct RadiotapTransmissionHeader
 {
+
   /**
-   *
+   * First we begin with the 'generic' header we also get when receiving
+   * messages.
    */
-  struct ieee80211_radiotap_header header;
+  struct Ieee80211RadiotapHeader header;
 
   /**
-   *
+   * Transmission rate (we use 0, kernel makes up its mind anyway).
    */
   uint8_t rate;
 
   /**
-   *
+   * Padding (we use 0).  There is a requirement to pad args, so that
+   * args of a given length must begin at a boundary of that length.
+   * As our next argument is the 'it_len' with 2 bytes, we need 1 byte
+   * of padding.
    */
   uint8_t pad1;
 
   /**
-   *
+   * Transmission flags from on the IEEE80211_RADIOTAP_F_TX_* constant family.
    */
   uint16_t txflags;
+
 };
 
+/**
+ * The above 'struct RadiotapTransmissionHeader' should have the
+ * following value for 'header.it_present' based on the presence of
+ * the 'rate' and 'txflags' in the overall struct.
+ */
+#define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_TX_FLAGS))
+
+
 
 /**
- * IO buffer used for buffering data in transit (to wireless or to stdout).
+ * struct Ieee80211RadiotapHeaderIterator - tracks walk through present radiotap arguments
+ * in the radiotap header.  Used when we parse radiotap packets received from the kernel.
  */
-struct SendBuffer
+struct Ieee80211RadiotapHeaderIterator
 {
   /**
-   * How many bytes of data are stored in 'buf' for transmission right now?
-   * Data always starts at offset 0 and extends to 'size'.
+   * pointer to the radiotap header we are walking through
    */
-  size_t size;
+  const struct Ieee80211RadiotapHeader *rtheader;
 
   /**
-   * How many bytes that were stored in 'buf' did we already write to the
-   * destination?  Always smaller than 'size'.
+   * pointer to current radiotap arg
    */
-  size_t pos;
-  
+  const uint8_t *this_arg;
+
   /**
-   * Buffered data; twice the maximum allowed message size as we add some
-   * headers.
+   * internal next argument pointer
    */
-  char buf[MAXLINE * 2];
-};
-
-/**
- * Buffer for data read from stdin to be transmitted to the wirless card.
- */
-static struct SendBuffer write_pout;
-
-/**
- * Buffer for data read from the wireless card to be transmitted to stdout.
- */
-static struct SendBuffer write_std;
-
-
+  const uint8_t *arg;
 
-
-/**
- * struct for storing the information of the hardware
- */
-struct HardwareInfos
-{
+  /**
+   * internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT is used).
+   */
+  const uint32_t *next_bitmap;
 
   /**
-   * file descriptor for the raw socket
+   * length of radiotap header in host byte ordering
    */
-  int fd_raw;
+  size_t max_length;
 
   /**
-   * Which format has the header that we're getting when receiving packets?
-   * Some  ARPHRD_IEEE80211_XXX-value.
+   * internal shifter for current uint32_t bitmap, (it_present in host byte order),
+   * If bit 0 is set, the 'arg_index' argument is present.
    */
-  int arptype_in;
+  uint32_t bitmap_shifter;
 
   /**
-   * Name of the interface, not necessarily 0-terminated (!).
+   * IEEE80211_RADIOTAP_... index of current arg
    */
-  char iface[IFNAMSIZ];
+  unsigned int this_arg_index;
 
   /**
-   * MAC address of our own WLAN interface.
+   * internal next argument index
    */
-  struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
+  unsigned int arg_index;
+
 };
 
 
+/* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
+
+/* ************************** our globals ******************************* */
+
 /**
- * struct ieee80211_radiotap_iterator - tracks walk through present radiotap arguments
- * in the radiotap header.
+ * struct for storing the information of the hardware.  There is only
+ * one of these.
  */
-struct ieee80211_radiotap_iterator
+struct HardwareInfos
 {
-  /**
-   * pointer to the radiotap header we are walking through
-   */
-  const struct ieee80211_radiotap_header *rtheader;
-
-  /**
-   * length of radiotap header in cpu byte ordering
-   */
-  size_t max_length;
 
   /**
-   * IEEE80211_RADIOTAP_... index of current arg
+   * file descriptor for the raw socket
    */
-  unsigned int this_arg_index;
+  int fd_raw;
 
   /**
-   * pointer to current radiotap arg
+   * Which format has the header that we're getting when receiving packets?
+   * Some  ARPHRD_IEEE80211_XXX-value.
    */
-  uint8_t *this_arg;
+  int arptype_in;
 
   /**
-   * internal next argument index
+   * Name of the interface, not necessarily 0-terminated (!).
    */
-  unsigned int arg_index;
+  char iface[IFNAMSIZ];
 
   /**
-   * internal next argument pointer
+   * MAC address of our own WLAN interface.
    */
-  uint8_t *arg;
+  struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
+};
 
+
+/**
+ * IO buffer used for buffering data in transit (to wireless or to stdout).
+ */
+struct SendBuffer
+{
   /**
-   * internal pointer to next present uint32_t
+   * How many bytes of data are stored in 'buf' for transmission right now?
+   * Data always starts at offset 0 and extends to 'size'.
    */
-  uint32_t *next_bitmap;
+  size_t size;
 
   /**
-   * internal shifter for curr uint32_t bitmap, b0 set == arg present
+   * How many bytes that were stored in 'buf' did we already write to the
+   * destination?  Always smaller than 'size'.
    */
-  uint32_t bitmap_shifter;
+  size_t pos;
+  
+  /**
+   * Buffered data; twice the maximum allowed message size as we add some
+   * headers.
+   */
+  char buf[MAXLINE * 2];
 };
 
 
+/**
+ * Buffer for data read from stdin to be transmitted to the wirless card.
+ */
+static struct SendBuffer write_pout;
+
+/**
+ * Buffer for data read from the wireless card to be transmitted to stdout.
+ */
+static struct SendBuffer write_std;
+
+
 
-/* specialized version of server_mst.c begins here */
+/* *********** specialized version of server_mst.c begins here ********** */
 
+/**
+ * To what multiple do we align messages?  8 byte should suffice for everyone
+ * for now.
+ */
 #define ALIGN_FACTOR 8
 
 /**
@@ -520,7 +836,6 @@ struct MessageStreamTokenizer
 };
 
 
-
 /**
  * Create a message stream tokenizer.
  *
@@ -536,10 +851,16 @@ mst_create (MessageTokenizerCallback cb,
 
   ret = malloc (sizeof (struct MessageStreamTokenizer));
   if (NULL == ret)
+  {
+    fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
     exit (1);
+  }
   ret->hdr = malloc (MIN_BUFFER_SIZE);
   if (NULL == ret->hdr)
-    exit (2);
+  {
+    fprintf (stderr, "Failed to allocate buffer for alignment\n");
+    exit (1);
+  }
   ret->curr_buf = MIN_BUFFER_SIZE;
   ret->cb = cb;
   ret->cb_cls = cb_cls;
@@ -600,8 +921,9 @@ do_align:
     want = ntohs (hdr->size);
     if (want < sizeof (struct GNUNET_MessageHeader))
     {
-      // GNUNET_break_op (0);
-      return GNUNET_SYSERR;
+      fprintf (stderr,
+              "Received invalid message from stdin\n");
+      exit (1);
     }
     if (mst->curr_buf - mst->off < want)
     {
@@ -614,7 +936,10 @@ do_align:
     {
       mst->hdr = realloc (mst->hdr, want);
       if (NULL == mst->hdr)
-       exit (3);
+      {
+       fprintf (stderr, "Failed to allocate buffer for alignment\n");
+       exit (1);
+      }
       ibuf = (char *) mst->hdr;
       mst->curr_buf = want;
     }
@@ -653,9 +978,9 @@ do_align:
       want = ntohs (hdr->size);
       if (want < sizeof (struct GNUNET_MessageHeader))
       {
-        // GNUNET_break_op (0);
-        mst->off = 0;
-        return GNUNET_SYSERR;
+       fprintf (stderr,
+                "Received invalid message from stdin\n");
+       exit (1);
       }
       if (size < want)
         break;                  /* or not, buffer incomplete, so copy to private buffer... */
@@ -676,11 +1001,19 @@ do_align:
     {
       mst->hdr = realloc (mst->hdr, size + mst->pos);
       if (NULL == mst->hdr)
-       exit (4);
+      {
+       fprintf (stderr, "Failed to allocate buffer for alignment\n");
+       exit (1);
+      }
       ibuf = (char *) mst->hdr;
       mst->curr_buf = size + mst->pos;
     }
-    // GNUNET_assert (mst->pos + size <= mst->curr_buf);
+    if (mst->pos + size > mst->curr_buf)
+    {
+      fprintf (stderr,
+              "Assertion failed\n");
+      exit (1);
+    }
     memcpy (&ibuf[mst->pos], buf, size);
     mst->pos += size;
   }
@@ -700,16 +1033,16 @@ mst_destroy (struct MessageStreamTokenizer *mst)
   free (mst);
 }
 
-/* end of server_mst.c copy */
-
+/* *****************  end of server_mst.c clone ***************** **/
 
 
+/* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */
 
 /**
  * Radiotap header iteration
  *
  * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
- * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
+ * struct Ieee80211RadiotapHeaderIterator (no need to init the struct beforehand)
  * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
  * if there are no more args in the header, or the next argument type index
  * that is present.  The iterator's this_arg member points to the start of the
@@ -723,9 +1056,8 @@ mst_destroy (struct MessageStreamTokenizer *mst)
  * @return 0 on success, -1 on error
  */
 static int
-ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
-                                  const struct ieee80211_radiotap_header
-                                  *radiotap_header, 
+ieee80211_radiotap_iterator_init (struct Ieee80211RadiotapHeaderIterator *iterator,
+                                  const struct Ieee80211RadiotapHeader *radiotap_header, 
                                  size_t max_length)
 {
   if ( (iterator == NULL) ||
@@ -737,26 +1069,22 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
     return -1;
 
   /* sanity check for allowed length and radiotap length field */
-  if ( (max_length < sizeof (struct ieee80211_radiotap_header)) ||
+  if ( (max_length < sizeof (struct Ieee80211RadiotapHeader)) ||
        (max_length < (GNUNET_le16toh (radiotap_header->it_len))) )
     return -1;
 
+  memset (iterator, 0, sizeof (struct Ieee80211RadiotapHeaderIterator));
   iterator->rtheader = radiotap_header;
   iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
-  iterator->arg_index = 0;
   iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
-  iterator->arg =
-      ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
-  iterator->this_arg = 0;
+  iterator->arg = ((uint8_t *) radiotap_header) + sizeof (struct Ieee80211RadiotapHeader);
 
   /* find payload start allowing for extended bitmap(s) */
-  if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
+  if (0 != (iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
   {
-    while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
-           IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
+    while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
     {
       iterator->arg += sizeof (uint32_t);
-
       /*
        * check for insanity where the present bitmaps
        * keep claiming to extend up to or even beyond the
@@ -778,7 +1106,7 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
 
 
 /**
- * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
+ * Returns the next radiotap parser iterator arg.
  *
  * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
  * and sets iterator->this_arg to point to the payload for the arg.  It takes
@@ -787,13 +1115,11 @@ ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
  * format.
  *
  * @param iterator: radiotap_iterator to move to next arg (if any)
- *
  * @return next present arg index on success or -1 if no more or error
  */
 static int
-ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
+ieee80211_radiotap_iterator_next (struct Ieee80211RadiotapHeaderIterator *iterator)
 {
-
   /*
    * small length lookup table for all radiotap types we heard of
    * starting from b0 in the bitmap, so we can walk the payload
@@ -838,120 +1164,103 @@ ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
    * for every radiotap entry we can at
    * least skip (by knowing the length)...
    */
-
   while (iterator->arg_index < sizeof (rt_sizes))
   {
-    int hit = 0;
-
-    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.
-     */
-
-    if ((((void *) iterator->arg) -
-         ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
-                                           - 1))
-      iterator->arg_index +=
-          (rt_sizes[iterator->arg_index] >> 4) -
-          ((((void *) iterator->arg) -
-            ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
-                                               4) - 1));
-
-    /*
-     * 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;
+    int hit = (0 != (iterator->bitmap_shifter & 1));
 
-    /*
-     * 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;
-
-next_entry:
+    if (hit)
+    {
+      unsigned int wanted_alignment;
+      unsigned int unalignment;
+      /*
+       * 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.  First, 'wanted_alignment' is set to be
+       * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit
+       * arguments.  Then, we calculate the 'unalignment' (how many
+       * bytes we are over by taking the difference of 'arg' and the
+       * overall starting point modulo the desired alignment.  As
+       * desired alignments are powers of two, we can do modulo with
+       * binary "&" (and also avoid the possibility of a division by
+       * zero if the 'rt_sizes' table contains bogus entries).
+       *
+       * 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, thus we
+       * need to really look at the delta here.
+       */
+      wanted_alignment = rt_sizes[iterator->arg_index] >> 4;
+      unalignment = (((void *) iterator->arg) - ((void *) iterator->rtheader)) & (wanted_alignment - 1);
+      if (0 != unalignment)
+      {
+       /* 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) */ 
+      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;      
+    }
 
+    /* Now, move on to next bit / next entry */
     iterator->arg_index++;
-    if (((iterator->arg_index & 31) == 0))
+
+    if (0 == (iterator->arg_index % 32))
     {
       /* completed current uint32_t bitmap */
-      if (iterator->bitmap_shifter & 1)
+      if (0 != (iterator->bitmap_shifter & 1))
       {
-        /* b31 was set, there is more */
-        /* move to next uint32_t bitmap */
+        /* bit 31 was set, there is more; move to next uint32_t bitmap */
         iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
         iterator->next_bitmap++;
       }
       else
       {
-        /* no more bitmaps: end */
+        /* no more bitmaps: end (by setting arg_index to high, unsupported value) */
         iterator->arg_index = sizeof (rt_sizes);
       }
     }
     else
-    {                           /* just try the next bit */
+    {                           
+      /* just try the next bit (while loop will move on) */
       iterator->bitmap_shifter >>= 1;
     }
 
     /* if we found a valid arg earlier, return it now */
-
     if (hit)
       return iterator->this_arg_index;
-
   }
 
-  /* we don't know how to handle any more args, we're done */
-  return -1;
-}
-
-
-/**
- * Return the channel from the frequency (in Mhz)
- * @param frequency of the channel
- * @return number of the channel
- */
-static int
-get_channel_from_frequency (int frequency)
-{
-  if (frequency >= 2412 && frequency <= 2472)
-    return (frequency - 2407) / 5;
-  if (frequency == 2484)
-    return 14;
-  if (frequency >= 5000 && frequency <= 6100)
-    return (frequency - 5000) / 5;
+  /* we don't know how to handle any more args (or there are no more),
+     so we're done (this is not an error) */
   return -1;
 }
 
 
 /**
- * function to calculate the crc, the start of the calculation
+ * Calculate crc32, the start of the calculation
  *
  * @param buf buffer to calc the crc
  * @param len len of the buffer
@@ -1036,7 +1345,7 @@ calc_crc_osdep (const unsigned char *buf, size_t len)
 
 
 /**
- * Function to calculate and check crc of the wlan packet
+ * Calculate and check crc of the wlan packet
  *
  * @param buf buffer of the packet, with len + 4 bytes of data,
  *            the last 4 bytes being the checksum
@@ -1057,6 +1366,30 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len)
 }
 
 
+/* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */
+
+
+/* ************beginning of code for reading packets from kernel ************** */
+
+/**
+ * Return the channel from the frequency (in Mhz)
+ *
+ * @param frequency of the channel
+ * @return number of the channel
+ */
+static int
+get_channel_from_frequency (int32_t frequency)
+{
+  if (frequency >= 2412 && frequency <= 2472)
+    return (frequency - 2407) / 5;
+  if (frequency == 2484)
+    return 14;
+  if (frequency >= 5000 && frequency <= 6100)
+    return (frequency - 5000) / 5;
+  return -1;
+}
+
+
 /**
  * Get the channel used by our WLAN interface.
  *
@@ -1067,46 +1400,46 @@ static int
 linux_get_channel (const struct HardwareInfos *dev)
 {
   struct iwreq wrq;
-  int fd;
-  int frequency;
-  int chan;
+  int32_t frequency;
 
   memset (&wrq, 0, sizeof (struct iwreq));
   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
-  fd = dev->fd_raw;
-  if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
+  if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq))
     return -1;
-
-  frequency = wrq.u.freq.m;
+  frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */
   if (100000000 < frequency)
     frequency /= 100000;
   else if (1000000 < frequency)
     frequency /= 1000;
   if (1000 < frequency)
-    chan = get_channel_from_frequency (frequency);
-  else
-    chan = frequency;
-  return chan;
+    return get_channel_from_frequency (frequency);
+  return frequency;
 }
 
 
 /**
- * function to read from a wlan card
+ * Read from the raw socket (the wlan card), parse the packet and
+ * put the result into the buffer for transmission to 'stdout'.
+ *
  * @param dev pointer to the struct of the wlan card
- * @param buf buffer to read to
+ * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
+ *            followed by the actual payload
  * @param buf_size size of the buffer
- * @param ri radiotap_rx info
- * @return size read from the buffer
+ * @param ri where to write radiotap_rx info
+ * @return number of bytes written to 'buf'
  */
 static ssize_t
-linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
-            struct Radiotap_rx *ri)
+linux_read (struct HardwareInfos *dev, 
+           unsigned char *buf, size_t buf_size,
+            struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *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;
+  size_t n;
+  int got_signal = 0;
+  int got_noise = 0;
+  int got_channel = 0;
+  int fcs_removed = 0;
 
   caplen = read (dev->fd_raw, tmpbuf, buf_size);
   if (0 > caplen)
@@ -1117,171 +1450,190 @@ linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
     return -1;
   }
 
-  memset (buf, 0, buf_size);
-  memset (ri, 0, sizeof (*ri));
-
+  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 = *(uint64_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);
+      const struct PrismHeader *ph;
+
+      ph = (const struct PrismHeader*) tmpbuf;
+      n = ph->msglen;
+      if ( (n < 8) || (n >= caplen) )
+       return 0; /* invalid format */
+      if ( (PRISM_MSGCODE_MONITOR == ph->msgcode) &&
+          (n >= sizeof (struct PrismHeader)) )
+      {
+       const char *pos;
+       size_t left;
+       struct PrismValue pv;
+       
+       left = n - sizeof (struct PrismHeader);
+       pos = (const char *) &ph[1];
+       while (left > sizeof (struct PrismValue))
+       {
+         left -= sizeof (struct PrismValue);
+         memcpy (&pv, pos, sizeof (struct PrismValue));
+         pos += sizeof (struct PrismValue);
+
+         switch (pv.did)
+         {
+         case PRISM_DID_NOISE:
+           if (PRISM_STATUS_OK == pv.status)
+           {
+             ri->ri_noise = pv.data;
+             got_noise = 1;
+           }
+           break;
+         case PRISM_DID_RATE:
+           if (PRISM_STATUS_OK == pv.status)
+             ri->ri_rate = pv.data * 500000;
+           break;
+         case PRISM_DID_CHANNEL:
+           if (PRISM_STATUS_OK == pv.status)
+           {
+             ri->ri_channel = pv.data;
+             got_channel = 1;
+           }
+           break;
+         case PRISM_DID_MACTIME:
+           if (PRISM_STATUS_OK == pv.status)
+             ri->ri_mactime = pv.data;
+           break;
+         case PRISM_DID_SIGNAL:
+           if (PRISM_STATUS_OK == pv.status)
+           {
+             ri->ri_power = pv.data;
+             got_signal = 1;
+           }
+           break;
+         }
+       }
+      } 
+      if ( (n < 8) || (n >= caplen) )
+       return 0; /* invalid format */
     }
-
-    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 (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
-      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)
+      struct Ieee80211RadiotapHeaderIterator iterator;
+      struct Ieee80211RadiotapHeader *rthdr;
+
+      memset (&iterator, 0, sizeof (iterator));
+      rthdr = (struct Ieee80211RadiotapHeader *) tmpbuf;
+      n = GNUNET_le16toh (rthdr->it_len);
+      if ( (n < sizeof (struct Ieee80211RadiotapHeader)) || (n >= caplen))
+       return 0; /* invalid 'it_len' */
+      if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
+       return 0;
+      /* go through the radiotap arguments we have been given by the driver */
+      while (0 <= ieee80211_radiotap_iterator_next (&iterator))
       {
-
-      case IEEE80211_RADIOTAP_TSFT:
-        ri->ri_mactime = GNUNET_le64toh (*((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 = GNUNET_le16toh (rthdr->it_len);
-    if (n <= 0 || n >= caplen)
-      return 0;
-  }
+       switch (iterator.this_arg_index)
+       {
+       case IEEE80211_RADIOTAP_TSFT:
+         ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
+         break;
+       case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+         if (!got_signal)
+         {
+           ri->ri_power = * ((int8_t*) iterator.this_arg);
+           got_signal = 1;       
+         }
+         break;
+       case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+         if (!got_signal)
+         {
+           ri->ri_power = * ((int8_t*) iterator.this_arg);
+           got_signal = 1;
+         }
+         break;
+       case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+         if (!got_noise)
+         {
+           ri->ri_noise = * ((int8_t*) iterator.this_arg);
+           got_noise = 1;
+         }
+         break;
+       case IEEE80211_RADIOTAP_DB_ANTNOISE:
+         if (!got_noise)
+         {
+           ri->ri_noise = * ((int8_t*) iterator.this_arg);
+           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:
+         {
+           uint8_t flags = *iterator.this_arg;
+           /* is the CRC visible at the end? if so, remove */
+           if (0 != (flags & IEEE80211_RADIOTAP_F_FCS))
+           {
+             fcs_removed = 1;
+             caplen -= sizeof (uint32_t);
+           }
+           break;
+         }
+       case IEEE80211_RADIOTAP_RX_FLAGS:
+         {
+           uint16_t flags = ntohs (* ((uint16_t *) iterator.this_arg));
+           if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS))
+             return 0;
+         }
+         break;
+       } /* end of 'switch' */
+      } /* end of the 'while' loop */
+    }       
     break;
   case ARPHRD_IEEE80211:
-    /* do nothing? */
+    n = 0; /* no header */
     break;
+  case ARPHRD_ETHER:
+    {
+      if (sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
+       return 0; /* invalid */
+      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;
+    errno = ENOTSUP; /* unsupported format */
     return -1;
   }
-
   caplen -= n;
+  if (! got_channel)
+    ri->ri_channel = linux_get_channel (dev);
 
-  //detect fcs 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 - 4)))
+  /* 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))) )  
   {
-    caplen -= 4;
+    /* NOTE: this heuristic can of course fail if there happens to
+       be a matching checksum at the end. Would be good to have
+       some data to see how often this heuristic actually works. */
+    caplen -= sizeof (uint32_t);
   }
+  /* copy payload to target buffer */
   memcpy (buf, tmpbuf + n, caplen);
-  if (!got_channel)
-    ri->ri_channel = linux_get_channel (dev);
-
   return caplen;
 }
 
 
+/* ************end of code for reading packets from kernel ************** */
+
+/* ************other helper functions for main start here ************** */
+
+
 /**
  * Open the wireless network interface for reading/writing.
  *
@@ -1317,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));
@@ -1328,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;
   }
 
@@ -1370,7 +1731,8 @@ open_device_raw (struct HardwareInfos *dev)
 
   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))
   {
@@ -1387,11 +1749,12 @@ open_device_raw (struct HardwareInfos *dev)
       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);
+    fprintf (stderr, 
+            "Failed to enable promiscuous mode on interface `%.*s'\n",
+             IFNAMSIZ, 
+            dev->iface);
     return 1;
   }
-
   return 0;
 }
 
@@ -1410,21 +1773,22 @@ test_wlan_interface (const char *iface)
   struct stat sbuf;
   int ret;
 
-  /* mac80211 stack detection */
-  ret =
-      snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
-                iface);
+  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);
-    return 1;
+    fprintf (stderr, 
+            "Did not find 802.11 interface `%s'. Exiting.\n", 
+            iface);
+    exit (1);
   }
   return 0;
 }
 
 
 /**
- * Function to test incoming packets mac for being our own.
+ * Test incoming packets mac for being our own.
  *
  * @param taIeeeHeader buffer of the packet
  * @param dev the Hardware_Infos struct
@@ -1434,18 +1798,24 @@ 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;
-  if (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE))
-    return 0;
-  if (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE))
-    return 0;
-  return 1;
+    return 1; /* not a GNUnet ad-hoc package */
+  if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
+       (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
+    return 0; /* for us, or broadcast */
+  return 1; /* not for us */
 }
 
 
 /**
- * function to set the wlan header to make attacks more difficult
+ * Set the wlan header to sane values to make attacks more difficult
+ *
  * @param taIeeeHeader pointer to the header of the packet
  * @param dev pointer to the Hardware_Infos struct
  */
@@ -1453,15 +1823,18 @@ static void
 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
          const struct HardwareInfos *dev)
 {
-  taIeeeHeader->frame_control = ntohs (0x08); // FIXME: need to shift by 8?
+  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
   taIeeeHeader->addr2 = dev->pl_mac;
   taIeeeHeader->addr3 = mac_bssid_gnunet;
 }
 
 
 /**
- * function to process the data from the stdin
- * @param cls pointer to the device struct
+ * Process data from the stdin.  Takes the message, prepends the
+ * radiotap transmission header, forces the sender MAC to be correct
+ * and puts it into our buffer for transmission to the kernel.
+ *
+ * @param cls pointer to the device struct ('struct HardwareInfos*')
  * @param hdr pointer to the start of the packet
  */
 static void
@@ -1471,12 +1844,13 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
   size_t sendsize;
-  struct RadioTapheader rtheader;
+  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_HELPER_DATA != ntohs (hdr->type)) ) 
+       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
   {
     fprintf (stderr, "Received malformed message\n");
     exit (1);
@@ -1484,25 +1858,45 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
   if (MAXLINE < sendsize)
   {
-    fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
+    fprintf (stderr, "Packet too big for buffer\n");
     exit (1);
   }
   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
-  rtheader.header.it_version = 0; /* radiotap version */
-  rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */
-  rtheader.header.it_present = GNUNET_htole16 (0x00008004); /* our bitmap */
-  rtheader.rate = 0x00;
-  rtheader.pad1 = 0x00;
-  rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
-  rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
-  rtheader.rate = header->rate;
-  memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
-  wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
-  memcpy (wlanheader, &header->frame, sendsize);
-  /* payload contains MAC address, but we don't trust it, so we'll
-   * overwrite it with OUR MAC address again 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);
+    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);
+    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);
+    memcpy (write_pout.buf, &etheader, sizeof (etheader));
+    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;
+  }
 }
 
 
@@ -1527,33 +1921,29 @@ main (int argc, char *argv[])
   int stdin_open;
   struct MessageStreamTokenizer *stdin_mst;
   int raw_eno;
+  uid_t uid;
 
-  memset (&dev, 0, sizeof (dev));
-  dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
-  raw_eno = errno; /* remember for later */
-
-  /* drop privs */
-  {
-    uid_t uid = getuid ();
+  /* assert privs so we can modify the firewall rules! */
+  uid = getuid ();
 #ifdef HAVE_SETRESUID
-    if (0 != setresuid (uid, uid, uid))
-    {
-      fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
-      if (-1 != dev.fd_raw)
-       (void) close (dev.fd_raw);
-      return 1;
-    }
+  if (0 != setresuid (uid, 0, 0))
+  {
+    fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
+    return 254;
+  }
 #else
-    if (0 != (setuid (uid) | seteuid (uid)))
-    {
-      fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
-      if (-1 != dev.fd_raw)
-       (void) close (dev.fd_raw);
-      return 1;
-    }
+  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));
+  dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
+  raw_eno = errno; /* remember for later */
+
   /* now that we've dropped root rights, we can do error checking */
   if (2 != argc)
   {
@@ -1588,6 +1978,29 @@ main (int argc, char *argv[])
     return 1;
   }
 
+  /* drop privs */
+  {
+    uid_t uid = getuid ();
+#ifdef HAVE_SETRESUID
+    if (0 != setresuid (uid, uid, uid))
+    {
+      fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+      if (-1 != dev.fd_raw)
+       (void) close (dev.fd_raw);
+      return 1;
+    }
+#else
+    if (0 != (setuid (uid) | seteuid (uid)))
+    {
+      fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
+      if (-1 != dev.fd_raw)
+       (void) close (dev.fd_raw);
+      return 1;
+    }
+#endif
+  }
+
+
   /* send MAC address of the WLAN interface to STDOUT first */
   {
     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
@@ -1699,33 +2112,30 @@ main (int argc, char *argv[])
 
     if (FD_ISSET (dev.fd_raw, &rfds))
     {
-      struct GNUNET_MessageHeader *header;
-      struct Radiotap_rx *rxinfo;
-      struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *datastart;
+      struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
       ssize_t ret;
 
-      header = (struct GNUNET_MessageHeader *) write_std.buf;
-      rxinfo = (struct Radiotap_rx *) &header[1];
-      datastart = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &rxinfo[1];
+      rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
       ret =
-          linux_read (&dev, (unsigned char *) datastart,
-                      sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
-                      sizeof (struct GNUNET_MessageHeader), rxinfo);
+          linux_read (&dev, (unsigned char *) &rrm->frame,
+                      sizeof (write_std.buf) 
+                     - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
+                     + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
+                     rrm);
       if (0 > ret)
       {
         fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
         break;
       }
-      if ((0 < ret) && (0 == mac_test (datastart, &dev)))
+      if ((0 < ret) && (0 == mac_test (&rrm->frame, &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);
+        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);
       }
     }
-
   }
   /* Error handling, try to clean up a bit at least */
   mst_destroy (stdin_mst);