gnunet-helper-transport-wlan.c | gnunet-helper-transport-wlan.c | |||
---|---|---|---|---|
/* | /* | |||
This file is part of GNUnet. | 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) 2007, 2008, Andy Green <andy@warmcat.com> | |||
Copyright (C) 2009 Thomas d'Otreppe | Copyright (C) 2009 Thomas d'Otreppe | |||
GNUnet is free software; you can redistribute it and/or modify | GNUnet is free software; you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published | it under the terms of the GNU General Public License as published | |||
by the Free Software Foundation; either version 3, or (at your | by the Free Software Foundation; either version 3, or (at your | |||
option) any later version. | option) any later version. | |||
GNUnet is distributed in the hope that it will be useful, but | GNUnet is distributed in the hope that it will be useful, but | |||
WITHOUT ANY WARRANTY; without even the implied warranty of | WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
General Public License for more details. | General Public License for more details. | |||
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | |||
along with GNUnet; see the file COPYING. If not, write to the | along with GNUnet; see the file COPYING. If not, write to the | |||
Free Software Foundation, Inc., 59 Temple Place - Suite 330, | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |||
Boston, MA 02111-1307, USA. | Boston, MA 02111-1307, USA. | |||
*/ | */ | |||
/** | /** | |||
* @file src/transport/gnunet-helper-transport-wlan.c | * @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. | * This code will work under GNU/Linux only. | |||
* @author David Brodski | * @author David Brodski | |||
* @author Christian Grothoff | ||||
* | * | |||
* This program serves as the mediator between the wlan interface and | * This program will allow receiving and sending traffic from the WLAN | |||
* gnunet | * 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) | ||||
*/ | */ | |||
/*- | /*- | |||
* we use our local copy of ieee80211_radiotap.h | * we use our local copy of ieee80211_radiotap.h | |||
* | * | |||
* - since we can't support extensions we don't understand | * - since we can't support extensions we don't understand | |||
* - since linux does not include it in userspace headers | * - since linux does not include it in userspace headers | |||
* | * | |||
* Portions of this code were taken from the ieee80211_radiotap.h header, | * Portions of this code were taken from the ieee80211_radiotap.h header, | |||
* which is | * which is | |||
skipping to change at line 73 | skipping to change at line 109 | |||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | |||
* OF SUCH DAMAGE. | * OF SUCH DAMAGE. | |||
*/ | */ | |||
/* | /* | |||
* Modifications to fit into the linux IEEE 802.11 stack, | * Modifications to fit into the linux IEEE 802.11 stack, | |||
* Mike Kershaw (dragorn@kismetwireless.net) | * Mike Kershaw (dragorn@kismetwireless.net) | |||
*/ | */ | |||
/* | ||||
/** | ||||
* parts taken from aircrack-ng, parts changend. | * parts taken from aircrack-ng, parts changend. | |||
*/ | */ | |||
#define _GNU_SOURCE | #define _GNU_SOURCE | |||
#include <sys/socket.h> | #include <sys/socket.h> | |||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <sys/wait.h> | #include <sys/wait.h> | |||
#include <sys/time.h> | #include <sys/time.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <netpacket/packet.h> | #include <netpacket/packet.h> | |||
#include <linux/if_ether.h> | #include <linux/if_ether.h> | |||
skipping to change at line 105 | skipping to change at line 141 | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <errno.h> | #include <errno.h> | |||
#include <dirent.h> | #include <dirent.h> | |||
#include <sys/param.h> | #include <sys/param.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <stdint.h> | #include <stdint.h> | |||
#include "gnunet_protocols.h" | #include "gnunet_protocols.h" | |||
#include "plugin_transport_wlan.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 | #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_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 MAXLINE 4096 | |||
#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000 | /* ********* structure of messages of type ARPHRD_IEEE80211_PRISM ********* ** */ | |||
/* Name Data type Units | /** | |||
* ---- --------- ----- | * Device name length in PRISM frames. | |||
* | * (In the kernel, this is "WLAN_DEVNAMELEN_MAX") | |||
* IEEE80211_RADIOTAP_TSFT __le64 microseconds | */ | |||
* | #define PRISM_DEVICE_NAME_LENGTH 16 | |||
* 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. | * Monitor Frame (indicator that we have a 'struct PrismHeader'). | |||
* | */ | |||
* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap | #define PRISM_MSGCODE_MONITOR 0x0041 | |||
* | ||||
* Tx/Rx frequency in MHz, followed by flags (see below). | /** | |||
* | * Mac time element. In micro-seconds. | |||
* IEEE80211_RADIOTAP_FHSS __le16 see below | * Drivers appear to use a 64bit counter to hold mactime internal | |||
* | * the then fill the prism header with the lower 32 bits | |||
* For frequency-hopping radios, the hop set (first byte) | */ | |||
* and pattern (second byte). | #define PRISM_DID_MACTIME 0x2041 | |||
* | ||||
* IEEE80211_RADIOTAP_RATE uint8_t 500kb/s | /** | |||
* | * Channel element | |||
* Tx/Rx data rate | */ | |||
* | #define PRISM_DID_CHANNEL 0x3041 | |||
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from | ||||
* one milliwatt (dBm) | /** | |||
* | * Signal element. Should be the signal strength in dbm, some people | |||
* RF signal power at the antenna, decibel difference from | * suggest that instead "100 - (strength in dbm)" is used (to make this | |||
* one milliwatt. | * a positive integer). | |||
* | */ | |||
* IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from | #define PRISM_DID_SIGNAL 0x6041 | |||
* one milliwatt (dBm) | ||||
* | /** | |||
* RF noise power at the antenna, decibel difference from one | * Noise element | |||
* milliwatt. | */ | |||
* | #define PRISM_DID_NOISE 0x7041 | |||
* IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) | ||||
* | /** | |||
* RF signal power at the antenna, decibel difference from an | * Rate element, in units/multiples of 500Khz | |||
* arbitrary, fixed reference. | */ | |||
* | #define PRISM_DID_RATE 0x8041 | |||
* IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) | ||||
* | /** | |||
* RF noise power at the antenna, decibel difference from an | * Value is set (supplied) | |||
* arbitrary, fixed reference point. | */ | |||
* | #define PRISM_STATUS_OK 0 | |||
* IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless | ||||
* | /** | |||
* Quality of Barker code lock. Unitless. Monotonically | * Value not supplied. | |||
* nondecreasing with "better" lock strength. Called "Signal | */ | |||
* Quality" in datasheets. (Is there a standard way to measure | #define PRISM_STATUS_NO_VALUE 1 | |||
* this?) | ||||
* | /** | |||
* IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless | * Values in the 'struct PrismHeader'. All in host byte order (!). | |||
* | */ | |||
* Transmit power expressed as unitless distance from max | struct PrismValue | |||
* power set at factory calibration. 0 is max power. | { | |||
* Monotonically nondecreasing with lower power levels. | /** | |||
* | * This has a different ID for each parameter, see | |||
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) | * PRISM_DID_* constants. | |||
* | */ | |||
* Transmit power expressed as decibel distance from max power | uint32_t did; | |||
* set at factory calibration. 0 is max power. Monotonically | ||||
* nondecreasing with lower power levels. | /** | |||
* | * See PRISM_STATUS_*-constants. Note that they are unusual: 0 = set; 1 | |||
* IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from | = not set | |||
* one milliwatt (dBm) | */ | |||
* | uint16_t status; | |||
* Transmit power expressed as dBm (decibels from a 1 milliwatt | ||||
* reference). This is the absolute power level measured at | /** | |||
* the antenna port. | * length of data (which is always a uint32_t, but presumably this can be | |||
* | used | |||
* IEEE80211_RADIOTAP_FLAGS uint8_t bitmap | * to specify that fewer bytes are used (with values in 'len' from 0-4). | |||
* | We | |||
* Properties of transmitted and received frames. See flags | * ignore this field. | |||
* defined below. | */ | |||
* | uint16_t len; | |||
* IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index | ||||
* | /** | |||
* Unitless indication of the Rx/Tx antenna for this packet. | * The data value | |||
* The first antenna is antenna 0. | */ | |||
* | uint32_t data; | |||
* IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap | ||||
* | } __attribute__ ((packed)); | |||
* Properties of received frames. See flags defined below. | ||||
* | /** | |||
* IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap | * Prism header format ('struct p80211msg' in Linux). All in host byte ord | |||
* | er (!). | |||
* Properties of transmitted frames. See flags defined below. | */ | |||
* | struct PrismHeader | |||
* IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data | { | |||
* | /** | |||
* Number of rts retries a transmitted frame used. | * We expect this to be a PRISM_MSGCODE_*. | |||
* | */ | |||
* IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data | uint32_t msgcode; | |||
* | ||||
* Number of unicast retries a transmitted frame used. | /** | |||
* | * 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 | 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_TSFT = 0, | |||
/** | ||||
* IEEE80211_RADIOTAP_FLAGS uint8_t bitmap | ||||
* | ||||
* Properties of transmitted and received frames. See flags | ||||
* defined below. | ||||
*/ | ||||
IEEE80211_RADIOTAP_FLAGS = 1, | IEEE80211_RADIOTAP_FLAGS = 1, | |||
/** | ||||
* IEEE80211_RADIOTAP_RATE uint8_t 500kb/s | ||||
* | ||||
* Tx/Rx data rate | ||||
*/ | ||||
IEEE80211_RADIOTAP_RATE = 2, | 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_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_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_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_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_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_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_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_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_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_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_DB_ANTNOISE = 13, | |||
/** | ||||
* IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap | ||||
* | ||||
* Properties of received frames. See flags defined below. | ||||
*/ | ||||
IEEE80211_RADIOTAP_RX_FLAGS = 14, | 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_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_RTS_RETRIES = 16, | |||
/** | ||||
* IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data | ||||
* | ||||
* Number of unicast retries a transmitted frame used. | ||||
*/ | ||||
IEEE80211_RADIOTAP_DATA_RETRIES = 17, | IEEE80211_RADIOTAP_DATA_RETRIES = 17, | |||
/** | ||||
* Extension bit, used to indicate that more bits are needed for | ||||
* the bitmask. | ||||
*/ | ||||
IEEE80211_RADIOTAP_EXT = 31 | IEEE80211_RADIOTAP_EXT = 31 | |||
}; | }; | |||
/* For IEEE80211_RADIOTAP_FLAGS */ | /** | |||
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received | * Bitmask indicating an extension of the bitmask is used. | |||
* during CFP | * (Mask corresponding to IEEE80211_RADIOTAP_EXT). | |||
*/ | */ | |||
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received | #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT | |||
* with short | ) | |||
* preamble | ||||
*/ | /** | |||
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received | * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get | |||
* with WEP encryption | * as part of a 'struct Ieee80211RadiotapHeader' extension | |||
*/ | * if the IEEE80211_RADIOTAP_FLAGS bit is set in | |||
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received | * 'it_present'). The radiotap flags are an 8-bit field. | |||
* with fragmentation | * | |||
*/ | * Frame was sent/received during CFP (Contention Free Period) | |||
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FC | */ | |||
S */ | #define IEEE80211_RADIOTAP_F_CFP 0x01 | |||
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding | ||||
between | /** | |||
* 802.11 header and payloa | * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get | |||
d | * as part of a 'struct Ieee80211RadiotapHeader' extension | |||
* (to 32-bit boundary) | * if the IEEE80211_RADIOTAP_FLAGS bit is set in | |||
*/ | * 'it_present'). The radiotap flags are an 8-bit field. | |||
/* 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 */ | ||||
/** | ||||
* 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. | ||||
* | * | |||
* I suggest the following extensible radio capture format. It is | * Frame was sent/received with short preamble | |||
* based on a bitmap indicating which fields are present. | */ | |||
#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 RadiotapTransmissi | ||||
onHeader'): | ||||
* failed due to excessive retries | ||||
*/ | ||||
#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 | ||||
/** | ||||
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissi | ||||
onHeader'): | ||||
* used cts 'protection' | ||||
*/ | ||||
#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 | ||||
/** | ||||
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissi | ||||
onHeader'): | ||||
* used rts/cts handshake | ||||
*/ | ||||
#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 | ||||
/** | ||||
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissi | ||||
onHeader'): | ||||
* frame should not be ACKed | ||||
*/ | ||||
#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 | ||||
/** | ||||
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissi | ||||
onHeader'): | ||||
* 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 | * I am trying to describe precisely what the application programmer | |||
* should expect in the following, and for that reason I tell the | * should expect in the following, and for that reason I tell the | |||
* units and origin of each measurement (where it applies), or else I | * units and origin of each measurement (where it applies), or else I | |||
* use sufficiently weaselly language ("is a monotonically nondecreasing | * use sufficiently weaselly language ("is a monotonically nondecreasing | |||
* function of...") that I cannot set false expectations for lawyerly | * function of...") that I cannot set false expectations for lawyerly | |||
* readers. | * readers. | |||
* | * | |||
* The radio capture header precedes the 802.11 header. | * The radio capture header precedes the 802.11 header. | |||
* All data in the header is little endian on all platforms. | * 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 | * Version 0. Only increases for drastic changes, introduction of | |||
* compatible new fields does not count. | * compatible new fields does not count. | |||
*/ | */ | |||
uint8_t it_version; | uint8_t it_version; | |||
/** | ||||
* Padding. Set to 0. | ||||
*/ | ||||
uint8_t it_pad; | uint8_t it_pad; | |||
/** | /** | |||
* length of the whole header in bytes, including it_version, | * length of the whole header in bytes, including it_version, | |||
* it_pad, it_len, and data fields. | * it_pad, it_len, and data fields. | |||
*/ | */ | |||
uint16_t it_len; | uint16_t it_len; | |||
/** | /** | |||
* A bitmap telling which fields are present. Set bit 31 | * A bitmap telling which fields are present. Set bit 31 | |||
* (0x80000000) to extend the bitmap by another 32 bits. Additional | * (0x80000000) to extend the bitmap by another 32 bits. Additional | |||
* extensions are made by setting bit 31. | * extensions are made by setting bit 31. | |||
*/ | */ | |||
uint32_t it_present; | 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; | 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; | uint8_t pad1; | |||
/** | /** | |||
* | * Transmission flags from on the IEEE80211_RADIOTAP_F_TX_* constant fami ly. | |||
*/ | */ | |||
uint16_t txflags; | uint16_t txflags; | |||
}; | }; | |||
/** | /** | |||
* IO buffer used for buffering data in transit (to wireless or to stdout). | * 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. | ||||
*/ | */ | |||
struct SendBuffer | #define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 << IEEE80211_RA | |||
DIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_TX_FLAGS)) | ||||
/** | ||||
* struct Ieee80211RadiotapHeaderIterator - tracks walk through present rad | ||||
iotap arguments | ||||
* in the radiotap header. Used when we parse radiotap packets received fr | ||||
om the kernel. | ||||
*/ | ||||
struct Ieee80211RadiotapHeaderIterator | ||||
{ | { | |||
/** | /** | |||
* How many bytes of data are stored in 'buf' for transmission right now? | * pointer to the radiotap header we are walking through | |||
* Data always starts at offset 0 and extends to 'size'. | ||||
*/ | */ | |||
size_t size; | const struct Ieee80211RadiotapHeader *rtheader; | |||
/** | /** | |||
* How many bytes that were stored in 'buf' did we already write to the | * pointer to current radiotap arg | |||
* destination? Always smaller than 'size'. | ||||
*/ | */ | |||
size_t pos; | const uint8_t *this_arg; | |||
/** | /** | |||
* Buffered data; twice the maximum allowed message size as we add some | * internal next argument pointer | |||
* headers. | ||||
*/ | */ | |||
char buf[MAXLINE * 2]; | const uint8_t *arg; | |||
}; | ||||
/** | /** | |||
* Buffer for data read from stdin to be transmitted to the wirless card. | * internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT i | |||
*/ | s used). | |||
static struct SendBuffer write_pout; | */ | |||
const uint32_t *next_bitmap; | ||||
/** | /** | |||
* Buffer for data read from the wireless card to be transmitted to stdout. | * length of radiotap header in host byte ordering | |||
*/ | */ | |||
static struct SendBuffer write_std; | size_t max_length; | |||
GNUNET_NETWORK_STRUCT_BEGIN | /** | |||
* 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; | ||||
/** | /** | |||
* generic definitions for IEEE 802.11 frames | * IEEE80211_RADIOTAP_... index of current arg | |||
*/ | */ | |||
struct ieee80211_frame | unsigned int this_arg_index; | |||
{ | ||||
uint8_t i_fc[2]; | /** | |||
uint8_t i_dur[2]; | * internal next argument index | |||
uint8_t i_addr1[IEEE80211_ADDR_LEN]; | */ | |||
uint8_t i_addr2[IEEE80211_ADDR_LEN]; | unsigned int arg_index; | |||
uint8_t i_addr3[IEEE80211_ADDR_LEN]; | ||||
uint8_t i_seq[2]; | }; | |||
/* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ | ||||
/* see below */ | /* ************** end of structure of ARPHRD_IEEE80211_FULL ************** | |||
} GNUNET_PACKED; | */ | |||
GNUNET_NETWORK_STRUCT_END | ||||
/* ************************** 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 | struct HardwareInfos | |||
{ | { | |||
/** | /** | |||
* file descriptor for the raw socket | * file descriptor for the raw socket | |||
*/ | */ | |||
int fd_raw; | int fd_raw; | |||
/** | /** | |||
skipping to change at line 420 | skipping to change at line 714 | |||
*/ | */ | |||
char iface[IFNAMSIZ]; | char iface[IFNAMSIZ]; | |||
/** | /** | |||
* MAC address of our own WLAN interface. | * MAC address of our own WLAN interface. | |||
*/ | */ | |||
struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac; | struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac; | |||
}; | }; | |||
/** | /** | |||
* struct ieee80211_radiotap_iterator - tracks walk through present radiota | * IO buffer used for buffering data in transit (to wireless or to stdout). | |||
p arguments | ||||
* in the radiotap header. | ||||
*/ | */ | |||
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; | ||||
/** | ||||
* length of radiotap header in cpu byte ordering | ||||
*/ | ||||
size_t max_length; | ||||
/** | ||||
* IEEE80211_RADIOTAP_... index of current arg | ||||
*/ | ||||
unsigned int this_arg_index; | ||||
/** | ||||
* pointer to current radiotap arg | ||||
*/ | */ | |||
uint8_t *this_arg; | size_t size; | |||
/** | /** | |||
* internal next argument index | * How many bytes that were stored in 'buf' did we already write to the | |||
* destination? Always smaller than 'size'. | ||||
*/ | */ | |||
unsigned int arg_index; | size_t pos; | |||
/** | /** | |||
* internal next argument pointer | * Buffered data; twice the maximum allowed message size as we add some | |||
* headers. | ||||
*/ | */ | |||
uint8_t *arg; | char buf[MAXLINE * 2]; | |||
}; | ||||
/** | /** | |||
* internal pointer to next present uint32_t | * Buffer for data read from stdin to be transmitted to the wirless card. | |||
*/ | */ | |||
uint32_t *next_bitmap; | static struct SendBuffer write_pout; | |||
/** | /** | |||
* internal shifter for curr uint32_t bitmap, b0 set == arg present | * Buffer for data read from the wireless card to be transmitted to stdout. | |||
*/ | */ | |||
uint32_t bitmap_shifter; | 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 everyo | ||||
ne | ||||
* for now. | ||||
*/ | ||||
#define ALIGN_FACTOR 8 | #define ALIGN_FACTOR 8 | |||
/** | /** | |||
* Smallest supported message. | * Smallest supported message. | |||
*/ | */ | |||
#define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader) | #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader) | |||
/** | /** | |||
* Functions with this signature are called whenever a | * Functions with this signature are called whenever a | |||
* complete message is received by the tokenizer. | * complete message is received by the tokenizer. | |||
skipping to change at line 540 | skipping to change at line 825 | |||
* @return handle to tokenizer | * @return handle to tokenizer | |||
*/ | */ | |||
static struct MessageStreamTokenizer * | static struct MessageStreamTokenizer * | |||
mst_create (MessageTokenizerCallback cb, | mst_create (MessageTokenizerCallback cb, | |||
void *cb_cls) | void *cb_cls) | |||
{ | { | |||
struct MessageStreamTokenizer *ret; | struct MessageStreamTokenizer *ret; | |||
ret = malloc (sizeof (struct MessageStreamTokenizer)); | ret = malloc (sizeof (struct MessageStreamTokenizer)); | |||
if (NULL == ret) | if (NULL == ret) | |||
{ | ||||
fprintf (stderr, "Failed to allocate buffer for tokenizer\n"); | ||||
exit (1); | exit (1); | |||
} | ||||
ret->hdr = malloc (MIN_BUFFER_SIZE); | ret->hdr = malloc (MIN_BUFFER_SIZE); | |||
if (NULL == ret->hdr) | if (NULL == ret->hdr) | |||
exit (2); | { | |||
fprintf (stderr, "Failed to allocate buffer for alignment\n"); | ||||
exit (1); | ||||
} | ||||
ret->curr_buf = MIN_BUFFER_SIZE; | ret->curr_buf = MIN_BUFFER_SIZE; | |||
ret->cb = cb; | ret->cb = cb; | |||
ret->cb_cls = cb_cls; | ret->cb_cls = cb_cls; | |||
return ret; | return ret; | |||
} | } | |||
/** | /** | |||
* Add incoming data to the receive buffer and call the | * Add incoming data to the receive buffer and call the | |||
* callback for all complete messages. | * callback for all complete messages. | |||
* | * | |||
skipping to change at line 603 | skipping to change at line 894 | |||
size -= delta; | size -= delta; | |||
} | } | |||
if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) | if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) | |||
{ | { | |||
return GNUNET_OK; | return GNUNET_OK; | |||
} | } | |||
hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | |||
want = ntohs (hdr->size); | want = ntohs (hdr->size); | |||
if (want < sizeof (struct GNUNET_MessageHeader)) | if (want < sizeof (struct GNUNET_MessageHeader)) | |||
{ | { | |||
// GNUNET_break_op (0); | fprintf (stderr, | |||
return GNUNET_SYSERR; | "Received invalid message from stdin\n"); | |||
exit (1); | ||||
} | } | |||
if (mst->curr_buf - mst->off < want) | if (mst->curr_buf - mst->off < want) | |||
{ | { | |||
/* need more space */ | /* need more space */ | |||
mst->pos -= mst->off; | mst->pos -= mst->off; | |||
memmove (ibuf, &ibuf[mst->off], mst->pos); | memmove (ibuf, &ibuf[mst->off], mst->pos); | |||
mst->off = 0; | mst->off = 0; | |||
} | } | |||
if (want > mst->curr_buf) | if (want > mst->curr_buf) | |||
{ | { | |||
mst->hdr = realloc (mst->hdr, want); | mst->hdr = realloc (mst->hdr, want); | |||
if (NULL == mst->hdr) | if (NULL == mst->hdr) | |||
exit (3); | { | |||
fprintf (stderr, "Failed to allocate buffer for alignment\n"); | ||||
exit (1); | ||||
} | ||||
ibuf = (char *) mst->hdr; | ibuf = (char *) mst->hdr; | |||
mst->curr_buf = want; | mst->curr_buf = want; | |||
} | } | |||
hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | |||
if (mst->pos - mst->off < want) | if (mst->pos - mst->off < want) | |||
{ | { | |||
delta = GNUNET_MIN (want - (mst->pos - mst->off), size); | delta = GNUNET_MIN (want - (mst->pos - mst->off), size); | |||
memcpy (&ibuf[mst->pos], buf, delta); | memcpy (&ibuf[mst->pos], buf, delta); | |||
mst->pos += delta; | mst->pos += delta; | |||
buf += delta; | buf += delta; | |||
skipping to change at line 656 | skipping to change at line 951 | |||
break; | break; | |||
offset = (unsigned long) buf; | offset = (unsigned long) buf; | |||
need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO; | need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO; | |||
if (GNUNET_NO == need_align) | if (GNUNET_NO == need_align) | |||
{ | { | |||
/* can try to do zero-copy and process directly from original buffer */ | /* can try to do zero-copy and process directly from original buffer */ | |||
hdr = (const struct GNUNET_MessageHeader *) buf; | hdr = (const struct GNUNET_MessageHeader *) buf; | |||
want = ntohs (hdr->size); | want = ntohs (hdr->size); | |||
if (want < sizeof (struct GNUNET_MessageHeader)) | if (want < sizeof (struct GNUNET_MessageHeader)) | |||
{ | { | |||
// GNUNET_break_op (0); | fprintf (stderr, | |||
mst->off = 0; | "Received invalid message from stdin\n"); | |||
return GNUNET_SYSERR; | exit (1); | |||
} | } | |||
if (size < want) | if (size < want) | |||
break; /* or not, buffer incomplete, so copy to pr ivate buffer... */ | break; /* or not, buffer incomplete, so copy to pr ivate buffer... */ | |||
mst->cb (mst->cb_cls, hdr); | mst->cb (mst->cb_cls, hdr); | |||
buf += want; | buf += want; | |||
size -= want; | size -= want; | |||
} | } | |||
else | else | |||
{ | { | |||
/* need to copy to private buffer to align; | /* need to copy to private buffer to align; | |||
* yes, we go a bit more spagetti than usual here */ | * yes, we go a bit more spagetti than usual here */ | |||
goto do_align; | goto do_align; | |||
} | } | |||
} | } | |||
if (size > 0) | if (size > 0) | |||
{ | { | |||
if (size + mst->pos > mst->curr_buf) | if (size + mst->pos > mst->curr_buf) | |||
{ | { | |||
mst->hdr = realloc (mst->hdr, size + mst->pos); | mst->hdr = realloc (mst->hdr, size + mst->pos); | |||
if (NULL == mst->hdr) | if (NULL == mst->hdr) | |||
exit (4); | { | |||
fprintf (stderr, "Failed to allocate buffer for alignment\n"); | ||||
exit (1); | ||||
} | ||||
ibuf = (char *) mst->hdr; | ibuf = (char *) mst->hdr; | |||
mst->curr_buf = size + mst->pos; | 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); | memcpy (&ibuf[mst->pos], buf, size); | |||
mst->pos += size; | mst->pos += size; | |||
} | } | |||
return ret; | return ret; | |||
} | } | |||
/** | /** | |||
* Destroys a tokenizer. | * Destroys a tokenizer. | |||
* | * | |||
* @param mst tokenizer to destroy | * @param mst tokenizer to destroy | |||
*/ | */ | |||
static void | static void | |||
mst_destroy (struct MessageStreamTokenizer *mst) | mst_destroy (struct MessageStreamTokenizer *mst) | |||
{ | { | |||
free (mst->hdr); | free (mst->hdr); | |||
free (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 | * Radiotap header iteration | |||
* | * | |||
* call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator | * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator | |||
* struct ieee80211_radiotap_iterator (no need to init the struct beforehan d) | * struct Ieee80211RadiotapHeaderIterator (no need to init the struct befor ehand) | |||
* then loop calling __ieee80211_radiotap_iterator_next()... it returns -1 | * 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 | * 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 | * that is present. The iterator's this_arg member points to the start of the | |||
* argument associated with the current argument index that is present, | * argument associated with the current argument index that is present, | |||
* which can be found in the iterator's this_arg_index member. This arg | * which can be found in the iterator's this_arg_index member. This arg | |||
* index corresponds to the IEEE80211_RADIOTAP_... defines. | * index corresponds to the IEEE80211_RADIOTAP_... defines. | |||
* | * | |||
* @param iterator iterator to initialize | * @param iterator iterator to initialize | |||
* @param radiotap_header message to parse | * @param radiotap_header message to parse | |||
* @param max_length number of valid bytes in radiotap_header | * @param max_length number of valid bytes in radiotap_header | |||
* @return 0 on success, -1 on error | * @return 0 on success, -1 on error | |||
*/ | */ | |||
static int | static int | |||
ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *itera | ieee80211_radiotap_iterator_init (struct Ieee80211RadiotapHeaderIterator *i | |||
tor, | terator, | |||
const struct ieee80211_radiotap_header | const struct Ieee80211RadiotapHeader *rad | |||
*radiotap_header, | iotap_header, | |||
size_t max_length) | size_t max_length) | |||
{ | { | |||
if ( (iterator == NULL) || | if ( (iterator == NULL) || | |||
(radiotap_header == NULL) ) | (radiotap_header == NULL) ) | |||
return -1; | return -1; | |||
/* Linux only supports version 0 radiotap format */ | /* Linux only supports version 0 radiotap format */ | |||
if (0 != radiotap_header->it_version) | if (0 != radiotap_header->it_version) | |||
return -1; | return -1; | |||
/* sanity check for allowed length and radiotap length field */ | /* 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))) ) | (max_length < (GNUNET_le16toh (radiotap_header->it_len))) ) | |||
return -1; | return -1; | |||
memset (iterator, 0, sizeof (struct Ieee80211RadiotapHeaderIterator)); | ||||
iterator->rtheader = radiotap_header; | iterator->rtheader = radiotap_header; | |||
iterator->max_length = GNUNET_le16toh (radiotap_header->it_len); | iterator->max_length = GNUNET_le16toh (radiotap_header->it_len); | |||
iterator->arg_index = 0; | ||||
iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present); | iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present); | |||
iterator->arg = | iterator->arg = ((uint8_t *) radiotap_header) + sizeof (struct Ieee80211R | |||
((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_hea | adiotapHeader); | |||
der); | ||||
iterator->this_arg = 0; | ||||
/* find payload start allowing for extended bitmap(s) */ | /* 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_MA SK)) | |||
{ | { | |||
while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & | while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & IEEE80211_RADIO | |||
IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) | TAP_PRESENT_EXTEND_MASK) | |||
{ | { | |||
iterator->arg += sizeof (uint32_t); | iterator->arg += sizeof (uint32_t); | |||
/* | /* | |||
* check for insanity where the present bitmaps | * check for insanity where the present bitmaps | |||
* keep claiming to extend up to or even beyond the | * keep claiming to extend up to or even beyond the | |||
* stated radiotap header length | * stated radiotap header length | |||
*/ | */ | |||
if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_l ength) | if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_l ength) | |||
return -1; | return -1; | |||
} | } | |||
iterator->arg += sizeof (uint32_t); | iterator->arg += sizeof (uint32_t); | |||
/* | /* | |||
* no need to check again for blowing past stated radiotap | * no need to check again for blowing past stated radiotap | |||
* header length, becuase ieee80211_radiotap_iterator_next | * header length, becuase ieee80211_radiotap_iterator_next | |||
* checks it before it is dereferenced | * checks it before it is dereferenced | |||
*/ | */ | |||
} | } | |||
/* we are all initialized happily */ | /* we are all initialized happily */ | |||
return 0; | return 0; | |||
} | } | |||
/** | /** | |||
* @brief ieee80211_radiotap_iterator_next - return next radiotap parser it erator arg | * Returns the next radiotap parser iterator arg. | |||
* | * | |||
* This function returns the next radiotap arg index (IEEE80211_RADIOTAP_.. .) | * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_.. .) | |||
* and sets iterator->this_arg to point to the payload for the arg. It tak es | * and sets iterator->this_arg to point to the payload for the arg. It tak es | |||
* care of alignment handling and extended present fields. interator->this _arg | * care of alignment handling and extended present fields. interator->this _arg | |||
* can be changed by the caller. The args pointed to are in little-endian | * can be changed by the caller. The args pointed to are in little-endian | |||
* format. | * format. | |||
* | * | |||
* @param iterator: radiotap_iterator to move to next arg (if any) | * @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 | * @return next present arg index on success or -1 if no more or error | |||
*/ | */ | |||
static int | static int | |||
ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *itera tor) | ieee80211_radiotap_iterator_next (struct Ieee80211RadiotapHeaderIterator *i terator) | |||
{ | { | |||
/* | /* | |||
* small length lookup table for all radiotap types we heard of | * small length lookup table for all radiotap types we heard of | |||
* starting from b0 in the bitmap, so we can walk the payload | * starting from b0 in the bitmap, so we can walk the payload | |||
* area of the radiotap header | * area of the radiotap header | |||
* | * | |||
* There is a requirement to pad args, so that args | * There is a requirement to pad args, so that args | |||
* of a given length must begin at a boundary of that length | * of a given length must begin at a boundary of that length | |||
* -- but note that compound args are allowed (eg, 2 x uint16_t | * -- but note that compound args are allowed (eg, 2 x uint16_t | |||
* for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not | * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not | |||
* a reliable indicator of alignment requirement. | * a reliable indicator of alignment requirement. | |||
skipping to change at line 836 | skipping to change at line 1134 | |||
/* | /* | |||
* add more here as they are defined in | * add more here as they are defined in | |||
* include/net/ieee80211_radiotap.h | * include/net/ieee80211_radiotap.h | |||
*/ | */ | |||
}; | }; | |||
/* | /* | |||
* for every radiotap entry we can at | * for every radiotap entry we can at | |||
* least skip (by knowing the length)... | * least skip (by knowing the length)... | |||
*/ | */ | |||
while (iterator->arg_index < sizeof (rt_sizes)) | 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 */ | ||||
/* | ||||
* 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; | 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->rtheade | ||||
r)) & (wanted_alignment - 1); | ||||
if (0 != unalignment) | ||||
{ | ||||
/* need padding (by 'wanted_alignment - unalignment') */ | ||||
iterator->arg_index += wanted_alignment - unalignment; | ||||
} | ||||
/* | /* | |||
* check for insanity where we are given a bitmap that | * this is what we will return to user, but we need to | |||
* claims to have more arg content than the length of the | * move on first so next call has something fresh to test | |||
* radiotap section. We will normally end up equalling this | */ | |||
* max_length on the last arg, never exceeding it. | iterator->this_arg_index = iterator->arg_index; | |||
*/ | iterator->this_arg = iterator->arg; | |||
if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | /* internally move on the size of this arg (using lower nybble from | |||
iterator->max_length) | the table) */ | |||
return -1; | iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; | |||
next_entry: | /* | |||
* 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)) > iter | ||||
ator->max_length) | ||||
return -1; | ||||
} | ||||
/* Now, move on to next bit / next entry */ | ||||
iterator->arg_index++; | iterator->arg_index++; | |||
if (((iterator->arg_index & 31) == 0)) | ||||
if (0 == (iterator->arg_index % 32)) | ||||
{ | { | |||
/* completed current uint32_t bitmap */ | /* completed current uint32_t bitmap */ | |||
if (iterator->bitmap_shifter & 1) | if (0 != (iterator->bitmap_shifter & 1)) | |||
{ | { | |||
/* b31 was set, there is more */ | /* bit 31 was set, there is more; move to next uint32_t bitmap */ | |||
/* move to next uint32_t bitmap */ | ||||
iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap); | iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap); | |||
iterator->next_bitmap++; | iterator->next_bitmap++; | |||
} | } | |||
else | else | |||
{ | { | |||
/* no more bitmaps: end */ | /* no more bitmaps: end (by setting arg_index to high, unsupported value) */ | |||
iterator->arg_index = sizeof (rt_sizes); | iterator->arg_index = sizeof (rt_sizes); | |||
} | } | |||
} | } | |||
else | else | |||
{ /* just try the next bit */ | { | |||
/* just try the next bit (while loop will move on) */ | ||||
iterator->bitmap_shifter >>= 1; | iterator->bitmap_shifter >>= 1; | |||
} | } | |||
/* if we found a valid arg earlier, return it now */ | /* if we found a valid arg earlier, return it now */ | |||
if (hit) | if (hit) | |||
return iterator->this_arg_index; | 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 -1; | |||
} | } | |||
/** | /** | |||
* Return the channel from the frequency (in Mhz) | * Calculate crc32, the start of the calculation | |||
* @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 | ||||
* | * | |||
* @param buf buffer to calc the crc | * @param buf buffer to calc the crc | |||
* @param len len of the buffer | * @param len len of the buffer | |||
* @return crc sum | * @return crc sum | |||
*/ | */ | |||
static unsigned long | static unsigned long | |||
calc_crc_osdep (const unsigned char *buf, size_t len) | calc_crc_osdep (const unsigned char *buf, size_t len) | |||
{ | { | |||
static const unsigned long int crc_tbl_osdep[256] = { | static const unsigned long int crc_tbl_osdep[256] = { | |||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, | |||
skipping to change at line 1031 | skipping to change at line 1313 | |||
}; | }; | |||
unsigned long crc = 0xFFFFFFFF; | unsigned long crc = 0xFFFFFFFF; | |||
for (; len > 0; len--, buf++) | for (; len > 0; len--, buf++) | |||
crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8); | crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8); | |||
return (~crc); | return (~crc); | |||
} | } | |||
/** | /** | |||
* 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, | * @param buf buffer of the packet, with len + 4 bytes of data, | |||
* the last 4 bytes being the checksum | * the last 4 bytes being the checksum | |||
* @param len length of the payload in data | * @param len length of the payload in data | |||
* @return 0 on success (checksum matches), 1 on error | * @return 0 on success (checksum matches), 1 on error | |||
*/ | */ | |||
static int | static int | |||
check_crc_buf_osdep (const unsigned char *buf, size_t len) | check_crc_buf_osdep (const unsigned char *buf, size_t len) | |||
{ | { | |||
unsigned long crc; | unsigned long crc; | |||
crc = calc_crc_osdep (buf, len); | crc = calc_crc_osdep (buf, len); | |||
buf += len; | buf += len; | |||
if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && | if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && | |||
((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]) | ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]) | |||
return 0; | return 0; | |||
return 1; | return 1; | |||
} | } | |||
/* ************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. | * Get the channel used by our WLAN interface. | |||
* | * | |||
* @param dev pointer to the dev struct of the card | * @param dev pointer to the dev struct of the card | |||
* @return channel number, -1 on error | * @return channel number, -1 on error | |||
*/ | */ | |||
static int | static int | |||
linux_get_channel (const struct HardwareInfos *dev) | linux_get_channel (const struct HardwareInfos *dev) | |||
{ | { | |||
struct iwreq wrq; | struct iwreq wrq; | |||
int fd; | int32_t frequency; | |||
int frequency; | ||||
int chan; | ||||
memset (&wrq, 0, sizeof (struct iwreq)); | memset (&wrq, 0, sizeof (struct iwreq)); | |||
strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); | strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); | |||
fd = dev->fd_raw; | if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq)) | |||
if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) | ||||
return -1; | return -1; | |||
frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep | ||||
frequency = wrq.u.freq.m; | it signed */ | |||
if (100000000 < frequency) | if (100000000 < frequency) | |||
frequency /= 100000; | frequency /= 100000; | |||
else if (1000000 < frequency) | else if (1000000 < frequency) | |||
frequency /= 1000; | frequency /= 1000; | |||
if (1000 < frequency) | if (1000 < frequency) | |||
chan = get_channel_from_frequency (frequency); | return get_channel_from_frequency (frequency); | |||
else | return frequency; | |||
chan = frequency; | ||||
return chan; | ||||
} | } | |||
/** | /** | |||
* 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 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_TRA | |||
NSPORT_WLAN_Ieee80211Frame', | ||||
* followed by the actual payload | ||||
* @param buf_size size of the buffer | * @param buf_size size of the buffer | |||
* @param ri radiotap_rx info | * @param ri where to write radiotap_rx info | |||
* @return size read from the buffer | * @return number of bytes written to 'buf' | |||
*/ | */ | |||
static ssize_t | static ssize_t | |||
linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size, | linux_read (struct HardwareInfos *dev, | |||
struct Radiotap_rx *ri) | unsigned char *buf, size_t buf_size, | |||
struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri) | ||||
{ | { | |||
unsigned char tmpbuf[buf_size]; | unsigned char tmpbuf[buf_size]; | |||
ssize_t caplen; | ssize_t caplen; | |||
int n, got_signal, got_noise, got_channel, fcs_removed; | size_t n; | |||
int got_signal = 0; | ||||
n = got_signal = got_noise = got_channel = fcs_removed = 0; | int got_noise = 0; | |||
int got_channel = 0; | ||||
int fcs_removed = 0; | ||||
caplen = read (dev->fd_raw, tmpbuf, buf_size); | caplen = read (dev->fd_raw, tmpbuf, buf_size); | |||
if (0 > caplen) | if (0 > caplen) | |||
{ | { | |||
if (EAGAIN == errno) | if (EAGAIN == errno) | |||
return 0; | return 0; | |||
fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errn o)); | fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errn o)); | |||
return -1; | return -1; | |||
} | } | |||
memset (buf, 0, buf_size); | ||||
memset (ri, 0, sizeof (*ri)); | memset (ri, 0, sizeof (*ri)); | |||
switch (dev->arptype_in) | switch (dev->arptype_in) | |||
{ | { | |||
case ARPHRD_IEEE80211_PRISM: | case ARPHRD_IEEE80211_PRISM: | |||
{ | ||||
/* skip the prism header */ | ||||
if (tmpbuf[7] == 0x40) | ||||
{ | { | |||
/* prism54 uses a different format */ | const struct PrismHeader *ph; | |||
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); | ||||
} | ||||
if ( (n < 8) || (n >= caplen) ) | ph = (const struct PrismHeader*) tmpbuf; | |||
return 0; | 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 */ | ||||
} | ||||
break; | break; | |||
case ARPHRD_IEEE80211_FULL: | 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) | ||||
{ | { | |||
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)) | ||||
{ | { | |||
switch (iterator.this_arg_index) | ||||
case IEEE80211_RADIOTAP_TSFT: | { | |||
ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg)) | case IEEE80211_RADIOTAP_TSFT: | |||
; | ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg) | |||
break; | ); | |||
break; | ||||
case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: | |||
if (!got_signal) | if (!got_signal) | |||
{ | { | |||
if (*iterator.this_arg < 127) | ri->ri_power = * ((int8_t*) iterator.this_arg); | |||
ri->ri_power = *iterator.this_arg; | got_signal = 1; | |||
else | } | |||
ri->ri_power = *iterator.this_arg - 255; | break; | |||
case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | ||||
got_signal = 1; | if (!got_signal) | |||
} | { | |||
break; | ri->ri_power = * ((int8_t*) iterator.this_arg); | |||
got_signal = 1; | ||||
case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | } | |||
if (!got_signal) | break; | |||
{ | case IEEE80211_RADIOTAP_DBM_ANTNOISE: | |||
if (*iterator.this_arg < 127) | if (!got_noise) | |||
ri->ri_power = *iterator.this_arg; | { | |||
else | ri->ri_noise = * ((int8_t*) iterator.this_arg); | |||
ri->ri_power = *iterator.this_arg - 255; | got_noise = 1; | |||
} | ||||
got_signal = 1; | break; | |||
} | case IEEE80211_RADIOTAP_DB_ANTNOISE: | |||
break; | if (!got_noise) | |||
{ | ||||
case IEEE80211_RADIOTAP_DBM_ANTNOISE: | ri->ri_noise = * ((int8_t*) iterator.this_arg); | |||
if (!got_noise) | got_noise = 1; | |||
{ | } | |||
if (*iterator.this_arg < 127) | break; | |||
ri->ri_noise = *iterator.this_arg; | case IEEE80211_RADIOTAP_ANTENNA: | |||
else | ri->ri_antenna = *iterator.this_arg; | |||
ri->ri_noise = *iterator.this_arg - 255; | break; | |||
case IEEE80211_RADIOTAP_CHANNEL: | ||||
got_noise = 1; | ri->ri_channel = *iterator.this_arg; | |||
} | got_channel = 1; | |||
break; | break; | |||
case IEEE80211_RADIOTAP_RATE: | ||||
case IEEE80211_RADIOTAP_DB_ANTNOISE: | ri->ri_rate = (*iterator.this_arg) * 500000; | |||
if (!got_noise) | break; | |||
{ | case IEEE80211_RADIOTAP_FLAGS: | |||
if (*iterator.this_arg < 127) | { | |||
ri->ri_noise = *iterator.this_arg; | uint8_t flags = *iterator.this_arg; | |||
else | /* is the CRC visible at the end? if so, remove */ | |||
ri->ri_noise = *iterator.this_arg - 255; | if (0 != (flags & IEEE80211_RADIOTAP_F_FCS)) | |||
{ | ||||
got_noise = 1; | fcs_removed = 1; | |||
} | caplen -= sizeof (uint32_t); | |||
break; | } | |||
break; | ||||
case IEEE80211_RADIOTAP_ANTENNA: | } | |||
ri->ri_antenna = *iterator.this_arg; | case IEEE80211_RADIOTAP_RX_FLAGS: | |||
break; | { | |||
uint16_t flags = ntohs (* ((uint16_t *) iterator.this_arg)); | ||||
case IEEE80211_RADIOTAP_CHANNEL: | if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS)) | |||
ri->ri_channel = *iterator.this_arg; | return 0; | |||
got_channel = 1; | } | |||
break; | break; | |||
} /* end of 'switch' */ | ||||
case IEEE80211_RADIOTAP_RATE: | } /* end of the 'while' loop */ | |||
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; | ||||
} | ||||
break; | break; | |||
case ARPHRD_IEEE80211: | case ARPHRD_IEEE80211: | |||
/* do nothing? */ | n = 0; /* no header */ | |||
break; | break; | |||
default: | default: | |||
errno = ENOTSUP; | errno = ENOTSUP; /* unsupported format */ | |||
return -1; | return -1; | |||
} | } | |||
caplen -= n; | 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 | /* 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 - | if ( (0 == fcs_removed) && | |||
4))) | (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); | memcpy (buf, tmpbuf + n, caplen); | |||
if (!got_channel) | ||||
ri->ri_channel = linux_get_channel (dev); | ||||
return caplen; | 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. | * Open the wireless network interface for reading/writing. | |||
* | * | |||
* @param dev pointer to the device struct | * @param dev pointer to the device struct | |||
* @return 0 on success | * @return 0 on success | |||
*/ | */ | |||
static int | static int | |||
open_device_raw (struct HardwareInfos *dev) | open_device_raw (struct HardwareInfos *dev) | |||
{ | { | |||
struct ifreq ifr; | struct ifreq ifr; | |||
skipping to change at line 1379 | skipping to change at line 1692 | |||
} | } | |||
/* enable promiscuous mode */ | /* enable promiscuous mode */ | |||
memset (&mr, 0, sizeof (mr)); | memset (&mr, 0, sizeof (mr)); | |||
mr.mr_ifindex = sll.sll_ifindex; | mr.mr_ifindex = sll.sll_ifindex; | |||
mr.mr_type = PACKET_MR_PROMISC; | mr.mr_type = PACKET_MR_PROMISC; | |||
if (0 != | if (0 != | |||
setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, | setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, | |||
sizeof (mr))) | sizeof (mr))) | |||
{ | { | |||
fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s' | fprintf (stderr, | |||
\n", | "Failed to enable promiscuous mode on interface `%.*s'\n", | |||
IFNAMSIZ, dev->iface); | IFNAMSIZ, | |||
dev->iface); | ||||
return 1; | return 1; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
/** | /** | |||
* Test if the given interface name really corresponds to a wireless | * Test if the given interface name really corresponds to a wireless | |||
* device. | * device. | |||
* | * | |||
* @param iface name of the interface | * @param iface name of the interface | |||
* @return 0 on success, 1 on error | * @return 0 on success, 1 on error | |||
*/ | */ | |||
static int | static int | |||
test_wlan_interface (const char *iface) | test_wlan_interface (const char *iface) | |||
{ | { | |||
char strbuf[512]; | char strbuf[512]; | |||
struct stat sbuf; | struct stat sbuf; | |||
int ret; | int ret; | |||
/* mac80211 stack detection */ | ret = snprintf (strbuf, sizeof (strbuf), | |||
ret = | "/sys/class/net/%s/phy80211/subsystem", | |||
snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsys | iface); | |||
tem", | ||||
iface); | ||||
if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) | if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) | |||
{ | { | |||
fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", ifac | fprintf (stderr, | |||
e); | "Did not find 802.11 interface `%s'. Exiting.\n", | |||
return 1; | iface); | |||
exit (1); | ||||
} | } | |||
return 0; | return 0; | |||
} | } | |||
/** | /** | |||
* Function to test incoming packets mac for being our own. | * Test incoming packets mac for being our own. | |||
* | * | |||
* @param uint8_taIeeeHeader buffer of the packet | * @param taIeeeHeader buffer of the packet | |||
* @param dev the Hardware_Infos struct | * @param dev the Hardware_Infos struct | |||
* @return 0 if mac belongs to us, 1 if mac is for another target | * @return 0 if mac belongs to us, 1 if mac is for another target | |||
*/ | */ | |||
static int | static int | |||
mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, | mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, | |||
const struct HardwareInfos *dev) | const struct HardwareInfos *dev) | |||
{ | { | |||
if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR | if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE)) | |||
_SIZE)) | return 1; /* not a GNUnet ad-hoc package */ | |||
return 1; | if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) || | |||
if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE | (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) ) | |||
)) | return 0; /* for us, or broadcast */ | |||
return 0; | return 1; /* not for us */ | |||
if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE) | ||||
) | ||||
return 0; | ||||
return 1; | ||||
} | } | |||
/** | /** | |||
* function to set the wlan header to make attacks more difficult | * Set the wlan header to sane values to make attacks more difficult | |||
* @param uint8_taIeeeHeader pointer to the header of the packet | * | |||
* @param taIeeeHeader pointer to the header of the packet | ||||
* @param dev pointer to the Hardware_Infos struct | * @param dev pointer to the Hardware_Infos struct | |||
*/ | */ | |||
static void | static void | |||
mac_set (struct ieee80211_frame *uint8_taIeeeHeader, | mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, | |||
const struct HardwareInfos *dev) | const struct HardwareInfos *dev) | |||
{ | { | |||
uint8_taIeeeHeader->i_fc[0] = 0x08; | taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA); | |||
uint8_taIeeeHeader->i_fc[1] = 0x00; | taIeeeHeader->addr2 = dev->pl_mac; | |||
memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE); | taIeeeHeader->addr3 = mac_bssid_gnunet; | |||
memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE); | ||||
} | } | |||
/** | /** | |||
* function to process the data from the stdin | * Process data from the stdin. Takes the message, prepends the | |||
* @param cls pointer to the device struct | * 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 | * @param hdr pointer to the start of the packet | |||
*/ | */ | |||
static void | static void | |||
stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) | stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) | |||
{ | { | |||
struct HardwareInfos *dev = cls; | struct HardwareInfos *dev = cls; | |||
struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1]; | const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header; | |||
struct ieee80211_frame *wlanheader; | struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader; | |||
size_t sendsize; | size_t sendsize; | |||
struct RadioTapheader rtheader; | struct RadiotapTransmissionHeader rtheader; | |||
rtheader.header.it_version = 0; /* radiotap version */ | ||||
rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length | ||||
*/ | ||||
rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap * | ||||
/ | ||||
rtheader.rate = 0x00; | ||||
rtheader.pad1 = 0x00; | ||||
rtheader.txflags = | ||||
GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_ | ||||
TX_NOSEQ); | ||||
sendsize = ntohs (hdr->size); | sendsize = ntohs (hdr->size); | |||
if (sendsize < | if ( (sendsize < | |||
sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) | sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) || | |||
(GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) | ||||
{ | { | |||
fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\ n"); | fprintf (stderr, "Received malformed message\n"); | |||
exit (1); | exit (1); | |||
} | } | |||
sendsize -= | sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - | |||
sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); | sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)); | |||
if (MAXLINE < sendsize) | 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); | ||||
} | ||||
if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) | ||||
{ | ||||
fprintf (stderr, "Function stdin_send_hw: wrong packet type\n"); | ||||
exit (1); | exit (1); | |||
} | } | |||
header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr; | ||||
rtheader.header.it_version = 0; | ||||
rtheader.header.it_pad = 0; | ||||
rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader)); | rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader)); | |||
rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANS MISSION_HEADER_MASK); | ||||
rtheader.rate = header->rate; | rtheader.rate = header->rate; | |||
rtheader.pad1 = 0; | ||||
rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80 | ||||
211_RADIOTAP_F_TX_NOSEQ); | ||||
memcpy (write_pout.buf, &rtheader, sizeof (rtheader)); | memcpy (write_pout.buf, &rtheader, sizeof (rtheader)); | |||
memcpy (write_pout.buf + sizeof (rtheader), &header[1], sendsize); | 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 | /* 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 */ | |||
wlanheader = (struct ieee80211_frame *) (write_pout.buf + sizeof (rtheade | ||||
r)); | ||||
mac_set (wlanheader, dev); | mac_set (wlanheader, dev); | |||
write_pout.size = sendsize + sizeof (rtheader); | write_pout.size = sendsize + sizeof (rtheader); | |||
} | } | |||
/** | /** | |||
* Main function of the helper. This code accesses a WLAN interface | * Main function of the helper. This code accesses a WLAN interface | |||
* in monitoring mode (layer 2) and then forwards traffic in both | * in monitoring mode (layer 2) and then forwards traffic in both | |||
* directions between the WLAN interface and stdin/stdout of this | * directions between the WLAN interface and stdin/stdout of this | |||
* process. Error messages are written to stdout. | * process. Error messages are written to stdout. | |||
* | * | |||
skipping to change at line 1695 | skipping to change at line 2004 | |||
if (0 == ret) | if (0 == ret) | |||
{ | { | |||
/* stop reading... */ | /* stop reading... */ | |||
stdin_open = 0; | stdin_open = 0; | |||
} | } | |||
mst_receive (stdin_mst, readbuf, ret); | mst_receive (stdin_mst, readbuf, ret); | |||
} | } | |||
if (FD_ISSET (dev.fd_raw, &rfds)) | if (FD_ISSET (dev.fd_raw, &rfds)) | |||
{ | { | |||
struct GNUNET_MessageHeader *header; | struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm; | |||
struct Radiotap_rx *rxinfo; | ||||
struct ieee80211_frame *datastart; | ||||
ssize_t ret; | ssize_t ret; | |||
header = (struct GNUNET_MessageHeader *) write_std.buf; | rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_s | |||
rxinfo = (struct Radiotap_rx *) &header[1]; | td.buf; | |||
datastart = (struct ieee80211_frame *) &rxinfo[1]; | ||||
ret = | ret = | |||
linux_read (&dev, (unsigned char *) datastart, | linux_read (&dev, (unsigned char *) &rrm->frame, | |||
sizeof (write_std.buf) - sizeof (struct Radiotap_rx) | sizeof (write_std.buf) | |||
- | - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceive | |||
sizeof (struct GNUNET_MessageHeader), rxinfo); | Message) | |||
+ sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame) | ||||
, | ||||
rrm); | ||||
if (0 > ret) | if (0 > ret) | |||
{ | { | |||
fprintf (stderr, "Read error from raw socket: %s\n", strerror (errn o)); | fprintf (stderr, "Read error from raw socket: %s\n", strerror (errn o)); | |||
break; | break; | |||
} | } | |||
if ((0 < ret) && (0 == mac_test (datastart, &dev))) | if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev))) | |||
{ | { | |||
write_std.size = | write_std.size = ret | |||
ret + sizeof (struct GNUNET_MessageHeader) + | + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) | |||
sizeof (struct Radiotap_rx); | - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame); | |||
header->size = htons (write_std.size); | rrm->header.size = htons (write_std.size); | |||
header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER | |||
); | ||||
} | } | |||
} | } | |||
} | } | |||
/* Error handling, try to clean up a bit at least */ | /* Error handling, try to clean up a bit at least */ | |||
mst_destroy (stdin_mst); | mst_destroy (stdin_mst); | |||
(void) close (dev.fd_raw); | (void) close (dev.fd_raw); | |||
return 1; /* we never exit 'normally' */ | return 1; /* we never exit 'normally' */ | |||
} | } | |||
/* end of gnunet-helper-transport-wlan.c */ | /* end of gnunet-helper-transport-wlan.c */ | |||
End of changes. 168 change blocks. | ||||
584 lines changed or deleted | 909 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |