gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r20581 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r20581 - gnunet/src/transport
Date: Fri, 16 Mar 2012 21:52:52 +0100

Author: grothoff
Date: 2012-03-16 21:52:52 +0100 (Fri, 16 Mar 2012)
New Revision: 20581

Modified:
   gnunet/src/transport/gnunet-helper-transport-wlan.c
   gnunet/src/transport/plugin_transport_wlan.c
   gnunet/src/transport/plugin_transport_wlan.h
Log:
-fixing misc. bugs and making wlan helper auditable, resolving #1939

Modified: gnunet/src/transport/gnunet-helper-transport-wlan.c
===================================================================
--- gnunet/src/transport/gnunet-helper-transport-wlan.c 2012-03-16 18:25:36 UTC 
(rev 20580)
+++ gnunet/src/transport/gnunet-helper-transport-wlan.c 2012-03-16 20:52:52 UTC 
(rev 20581)
@@ -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 <address@hidden>
    Copyright (C) 2009 Thomas d'Otreppe
 
@@ -21,12 +21,27 @@
 */
 /**
  * @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 interface to use.  Since it uses
+ * RAW sockets, it 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 (Mar 16th 2012)
  */
 
 /*-
@@ -102,180 +117,430 @@
 #include "gnunet_protocols.h"
 #include "plugin_transport_wlan.h"
 
+/**
+ * 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
+
+/**
+ * Packet format type for the messages we receive from 
+ * the kernel.  This is for messages with a
+ * 'struct Ieee80211RadiotapHeader' (see below).
+ */
 #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 */
+/**
+ * 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)
 
-/* 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 */
 
 
 /**
- * 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 during CFP (Contention Free Period)
+ */
+#define        IEEE80211_RADIOTAP_F_CFP        0x01
+
+/**
+ * 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 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
  * units and origin of each measurement (where it applies), or else I
@@ -286,7 +551,7 @@
  * 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
@@ -295,7 +560,7 @@
   uint8_t it_version;
 
   /**
-   *
+   * Padding.  Set to 0.  
    */
   uint8_t it_pad;
 
@@ -313,60 +578,106 @@
   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];
+  const uint8_t *arg;
+
+  /**
+   * internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT is 
used).
+   */
+  const uint32_t *next_bitmap;
+
+  /**
+   * length of radiotap header in host byte ordering
+   */
+  size_t max_length;
+
+  /**
+   * internal shifter for current uint32_t bitmap, (it_present in host byte 
order),
+   * If bit 0 is set, the 'arg_index' argument is present.
+   */
+  uint32_t bitmap_shifter;
+
+  /**
+   * IEEE80211_RADIOTAP_... index of current arg
+   */
+  unsigned int this_arg_index;
+
+  /**
+   * internal next argument index
+   */
+  unsigned int arg_index;
+
 };
 
 
+/* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
+
+/* ************************** our globals ******************************* */
+
 /**
- * struct for storing the information of the hardware
+ * struct for storing the information of the hardware.  There is only
+ * one of these.
  */
 struct HardwareInfos
 {
@@ -395,50 +706,27 @@
 
 
 /**
- * struct ieee80211_radiotap_iterator - tracks walk through present radiotap 
arguments
- * in the radiotap header.
+ * IO buffer used for buffering data in transit (to wireless or to stdout).
  */
-struct ieee80211_radiotap_iterator
+struct SendBuffer
 {
   /**
-   * pointer to the radiotap header we are walking through
+   * How many bytes of data are stored in 'buf' for transmission right now?
+   * Data always starts at offset 0 and extends to 'size'.
    */
-  const struct ieee80211_radiotap_header *rtheader;
+  size_t size;
 
   /**
-   * length of radiotap header in cpu byte ordering
+   * How many bytes that were stored in 'buf' did we already write to the
+   * destination?  Always smaller than 'size'.
    */
-  size_t max_length;
-
+  size_t pos;
+  
   /**
-   * IEEE80211_RADIOTAP_... index of current arg
+   * Buffered data; twice the maximum allowed message size as we add some
+   * headers.
    */
-  unsigned int this_arg_index;
-
-  /**
-   * pointer to current radiotap arg
-   */
-  uint8_t *this_arg;
-
-  /**
-   * internal next argument index
-   */
-  unsigned int arg_index;
-
-  /**
-   * internal next argument pointer
-   */
-  uint8_t *arg;
-
-  /**
-   * internal pointer to next present uint32_t
-   */
-  uint32_t *next_bitmap;
-
-  /**
-   * internal shifter for curr uint32_t bitmap, b0 set == arg present
-   */
-  uint32_t bitmap_shifter;
+  char buf[MAXLINE * 2];
 };
 
 
@@ -454,8 +742,12 @@
 
 
 
-/* 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
 
 /**
@@ -530,10 +822,16 @@
 
   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;
@@ -594,8 +892,9 @@
     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)
     {
@@ -608,7 +907,10 @@
     {
       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;
     }
@@ -647,9 +949,9 @@
       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... */
@@ -670,11 +972,19 @@
     {
       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;
   }
@@ -694,16 +1004,16 @@
   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
@@ -717,9 +1027,8 @@
  * @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) ||
@@ -731,26 +1040,22 @@
     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
@@ -772,7 +1077,7 @@
 
 
 /**
- * @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
@@ -781,13 +1086,11 @@
  * 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
@@ -832,120 +1135,103 @@
    * for every radiotap entry we can at
    * least skip (by knowing the length)...
    */
-
   while (iterator->arg_index < sizeof (rt_sizes))
   {
-    int hit = 0;
+    int hit = (0 != (iterator->bitmap_shifter & 1));
 
-    if (!(iterator->bitmap_shifter & 1))
-      goto next_entry;          /* arg not present */
+    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;
 
-    /*
-     * 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.
-     */
+      /* 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;      
+    }
 
-    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));
+    /* Now, move on to next bit / next entry */
+    iterator->arg_index++;
 
-    /*
-     * this is what we will return to user, but we need to
-     * move on first so next call has something fresh to test
-     */
-
-    iterator->this_arg_index = iterator->arg_index;
-    iterator->this_arg = iterator->arg;
-    hit = 1;
-
-    /* internally move on the size of this arg */
-
-    iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
-
-    /*
-     * check for insanity where we are given a bitmap that
-     * claims to have more arg content than the length of the
-     * radiotap section.  We will normally end up equalling this
-     * max_length on the last arg, never exceeding it.
-     */
-
-    if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
-        iterator->max_length)
-      return -1;
-
-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 */
+  /* 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;
 }
 
 
 /**
- * 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;
-  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
@@ -1030,7 +1316,7 @@
 
 
 /**
- * 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
@@ -1051,7 +1337,31 @@
 }
 
 
+/* ************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.
  *
  * @param dev pointer to the dev struct of the card
@@ -1061,36 +1371,33 @@
 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 where to write radiotap_rx info
- * @return size read from the buffer
+ * @return number of bytes written to 'buf'
  */
 static ssize_t
 linux_read (struct HardwareInfos *dev, 
@@ -1099,10 +1406,12 @@
 {
   unsigned char tmpbuf[buf_size];
   ssize_t caplen;
-  int n, got_signal, got_noise, got_channel, fcs_removed;
+  size_t n;
+  int got_signal = 0;
+  int got_noise = 0;
+  int got_channel = 0;
+  int fcs_removed = 0;
 
-  n = got_signal = got_noise = got_channel = fcs_removed = 0;
-
   caplen = read (dev->fd_raw, tmpbuf, buf_size);
   if (0 > caplen)
   {
@@ -1112,172 +1421,181 @@
     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;
+      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 */
     }
-    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);
-    }
-
-    if ( (n < 8) || (n >= caplen) )
-      return 0;
-  }
     break;
-
   case ARPHRD_IEEE80211_FULL:
-  {
-    struct ieee80211_radiotap_iterator iterator;
-    struct ieee80211_radiotap_header *rthdr;
-
-    memset (&iterator, 0, sizeof (iterator));
-    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)
     {
+      struct Ieee80211RadiotapHeaderIterator iterator;
+      struct Ieee80211RadiotapHeader *rthdr;
 
-      switch (iterator.this_arg_index)
+      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;
   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.
  *
@@ -1383,11 +1701,12 @@
       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;
 }
 
@@ -1406,21 +1725,22 @@
   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
@@ -1431,17 +1751,17 @@
           const struct HardwareInfos *dev)
 {
   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
  */
@@ -1449,15 +1769,18 @@
 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
@@ -1467,7 +1790,7 @@
   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
   size_t sendsize;
-  struct RadioTapheader rtheader;
+  struct RadiotapTransmissionHeader rtheader;
 
   sendsize = ntohs (hdr->size);
   if ( (sendsize <
@@ -1484,20 +1807,19 @@
     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.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);
-  rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
-  rtheader.rate = header->rate;
   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 again to prevent mischief */
+   * overwrite it with OUR MAC address to prevent mischief */
   mac_set (wlanheader, dev);
   write_pout.size = sendsize + sizeof (rtheader);
 }

Modified: gnunet/src/transport/plugin_transport_wlan.c
===================================================================
--- gnunet/src/transport/plugin_transport_wlan.c        2012-03-16 18:25:36 UTC 
(rev 20580)
+++ gnunet/src/transport/plugin_transport_wlan.c        2012-03-16 20:52:52 UTC 
(rev 20581)
@@ -93,6 +93,7 @@
  * max messages in in queue
  */
 #define MESSAGES_IN_QUEUE_SIZE 10
+
 /**
  * max messages in in queue per session/client
  */
@@ -106,18 +107,7 @@
 #define WLAN_LLC_SSAP_FIELD 0x1f
 
 
-#define IEEE80211_ADDR_LEN      6       /* size of 802.11 address */
 
-#define IEEE80211_FC0_VERSION_MASK              0x03
-#define IEEE80211_FC0_VERSION_SHIFT             0
-#define IEEE80211_FC0_VERSION_0                 0x00
-#define IEEE80211_FC0_TYPE_MASK                 0x0c
-#define IEEE80211_FC0_TYPE_SHIFT                2
-#define IEEE80211_FC0_TYPE_MGT                  0x00
-#define IEEE80211_FC0_TYPE_CTL                  0x04
-#define IEEE80211_FC0_TYPE_DATA                 0x08
-
-
 /**
  * Encapsulation of all of the state of the plugin.
  */
@@ -1266,7 +1256,7 @@
 {
   const int rate = 11000000;
 
-  Header->frame_control = htons (IEEE80211_FC0_TYPE_DATA); // FIXME: check: 
might need to shift by 8?
+  Header->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
   Header->addr1 = *to_mac_addr;
   Header->addr2 = plugin->mac_address;
   Header->addr3 = mac_bssid_gnunet;

Modified: gnunet/src/transport/plugin_transport_wlan.h
===================================================================
--- gnunet/src/transport/plugin_transport_wlan.h        2012-03-16 18:25:36 UTC 
(rev 20580)
+++ gnunet/src/transport/plugin_transport_wlan.h        2012-03-16 20:52:52 UTC 
(rev 20581)
@@ -34,6 +34,25 @@
  */
 #define MAC_ADDR_SIZE 6
 
+/**
+ * Value for "Management" in the 'frame_control' field of the
+ * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame.  
+ */
+#define IEEE80211_FC0_TYPE_MGT                  0x00
+
+/**
+ * Value for "Control" in the 'frame_control' field of the
+ * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame.
+ */
+#define IEEE80211_FC0_TYPE_CTL                  0x04
+
+/**
+ * Value for DATA in the 'frame_control' field of the
+ * struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame.
+ */
+#define IEEE80211_FC0_TYPE_DATA                 0x08
+
+
 GNUNET_NETWORK_STRUCT_BEGIN
 
 /**
@@ -68,7 +87,13 @@
 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame
 {
   /**
-   * 802.11 Frame Control field,
+   * 802.11 Frame Control field.  A bitmask.  The overall field is a
+   * 16-bit mask of the respecitve fields.  The lowest two bits should
+   * be 0, then comes the "type" (2 bits, see IEEE80211_FC0_TYPE_*
+   * constants), followed by 4-bit subtype (all zeros for ad-hoc),
+   * followed by various flags (to DS, from DS, more frag, retry,
+   * power management, more data, WEP, strict), all of which we also
+   * keep at zero.
    */
   uint16_t frame_control GNUNET_PACKED;
 
@@ -93,7 +118,8 @@
   struct GNUNET_TRANSPORT_WLAN_MacAddress addr3;
 
   /**
-   * 802.11 sequence control field.
+   * 802.11 sequence control field; contains fragment number an sequence
+   * number (we set this to all zeros).
    */
   uint16_t sequence_control GNUNET_PACKED;
 
@@ -162,46 +188,46 @@
   struct GNUNET_MessageHeader header;
 
   /**
-   * FIXME: not initialized properly so far. (supposed to contain
-   * information about which of the fields below are actually valid).
+   * Information about which of the fields below are actually valid.
+   * 0 for none.  FIXME: not properly initialized so far (always zero).
    */
   uint32_t ri_present GNUNET_PACKED;
 
   /**
-   * IEEE80211_RADIOTAP_TSFT
+   * IEEE80211_RADIOTAP_TSFT, 0 if unknown.
    */
   uint64_t ri_mactime GNUNET_PACKED;
 
   /**
    * from radiotap
    * either IEEE80211_RADIOTAP_DBM_ANTSIGNAL
-   * or IEEE80211_RADIOTAP_DB_ANTSIGNAL
+   * or IEEE80211_RADIOTAP_DB_ANTSIGNAL, 0 if unknown.
    */
   int32_t ri_power GNUNET_PACKED;
 
   /**
    * either IEEE80211_RADIOTAP_DBM_ANTNOISE
-   * or IEEE80211_RADIOTAP_DB_ANTNOISE
+   * or IEEE80211_RADIOTAP_DB_ANTNOISE, 0 if unknown.
    */
   int32_t ri_noise GNUNET_PACKED;
 
   /**
-   * IEEE80211_RADIOTAP_CHANNEL
+   * IEEE80211_RADIOTAP_CHANNEL, 0 if unknown.
    */
   uint32_t ri_channel GNUNET_PACKED;
 
   /**
-   * Frequency we use.  FIXME: not properly initialized so far!
+   * Frequency we use.  0 if unknown.
    */
   uint32_t ri_freq GNUNET_PACKED;
 
   /**
-   * IEEE80211_RADIOTAP_RATE * 50000
+   * IEEE80211_RADIOTAP_RATE * 50000, 0 if unknown.
    */
   uint32_t ri_rate GNUNET_PACKED;
 
   /**
-   * IEEE80211_RADIOTAP_ANTENNA
+   * IEEE80211_RADIOTAP_ANTENNA, 0 if unknown.
    */
   uint32_t ri_antenna GNUNET_PACKED;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]