-some more wlan code cleanup
[oweals/gnunet.git] / src / transport / gnunet-transport-wlan-helper.c
1 /*
2    This file is part of GNUnet.
3    (C) 2010, 2011 Christian Grothoff (and other contributing authors)
4    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5    Copyright (C) 2009 Thomas d'Otreppe
6
7    GNUnet is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11
12    GNUnet is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GNUnet; see the file COPYING.  If not, write to the
19    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21 */
22 /*-
23  * we use our local copy of ieee80211_radiotap.h
24  *
25  * - since we can't support extensions we don't understand
26  * - since linux does not include it in userspace headers
27  *
28  * Portions of this code were taken from the ieee80211_radiotap.h header,
29  * which is
30  *
31  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  * 3. The name of David Young may not be used to endorse or promote
42  *    products derived from this software without specific prior
43  *    written permission.
44  *
45  * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
46  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
47  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
48  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
49  * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
51  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
56  * OF SUCH DAMAGE.
57  */
58
59 /*
60  * Modifications to fit into the linux IEEE 802.11 stack,
61  * Mike Kershaw (dragorn@kismetwireless.net)
62  */
63
64 /**
65  * @file src/transport/gnunet-transport-wlan-helper.c
66  * @brief wlan layer two server; must run as root (SUID will do)
67  *        This code will work under GNU/Linux only.
68  * @author David Brodski
69  *
70  * This program serves as the mediator between the wlan interface and
71  * gnunet
72  */
73
74 /**
75  * parts taken from aircrack-ng, parts changend.
76  */
77 #define _GNU_SOURCE
78 #include <sys/socket.h>
79 #include <sys/ioctl.h>
80 #include <sys/types.h>
81 #include <unistd.h>
82 #include <sys/wait.h>
83 #include <sys/time.h>
84 #include <sys/stat.h>
85 #include <netpacket/packet.h>
86 #include <linux/if_ether.h>
87 #include <linux/if.h>
88 #include <linux/wireless.h>
89 #include <netinet/in.h>
90 #include <linux/if_tun.h>
91 #include <stdio.h>
92 #include <stdlib.h>
93 #include <string.h>
94 #include <stdarg.h>
95 #include <fcntl.h>
96 #include <errno.h>
97 #include <dirent.h>
98 #include <sys/param.h>
99 #include <endian.h>
100 #include <unistd.h>
101 #include <stdint.h>
102
103 #include "gnunet_protocols.h"
104 #include "gnunet_server_lib.h"
105 #include "plugin_transport_wlan.h"
106
107 #define ARPHRD_IEEE80211        801
108 #define ARPHRD_IEEE80211_PRISM  802
109 #define ARPHRD_IEEE80211_FULL   803
110
111 /**
112  * size of 802.11 address
113  */
114 #define IEEE80211_ADDR_LEN      6
115
116 #define MAXLINE 4096
117
118 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
119
120
121 /* Name                                 Data type    Units
122  * ----                                 ---------    -----
123  *
124  * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
125  *
126  *      Value in microseconds of the MAC's 64-bit 802.11 Time
127  *      Synchronization Function timer when the first bit of the
128  *      MPDU arrived at the MAC. For received frames, only.
129  *
130  * IEEE80211_RADIOTAP_CHANNEL           2 x __le16   MHz, bitmap
131  *
132  *      Tx/Rx frequency in MHz, followed by flags (see below).
133  *
134  * IEEE80211_RADIOTAP_FHSS              __le16       see below
135  *
136  *      For frequency-hopping radios, the hop set (first byte)
137  *      and pattern (second byte).
138  *
139  * IEEE80211_RADIOTAP_RATE              uint8_t           500kb/s
140  *
141  *      Tx/Rx data rate
142  *
143  * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
144  *                                                   one milliwatt (dBm)
145  *
146  *      RF signal power at the antenna, decibel difference from
147  *      one milliwatt.
148  *
149  * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
150  *                                                   one milliwatt (dBm)
151  *
152  *      RF noise power at the antenna, decibel difference from one
153  *      milliwatt.
154  *
155  * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t           decibel (dB)
156  *
157  *      RF signal power at the antenna, decibel difference from an
158  *      arbitrary, fixed reference.
159  *
160  * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t           decibel (dB)
161  *
162  *      RF noise power at the antenna, decibel difference from an
163  *      arbitrary, fixed reference point.
164  *
165  * IEEE80211_RADIOTAP_LOCK_QUALITY      __le16       unitless
166  *
167  *      Quality of Barker code lock. Unitless. Monotonically
168  *      nondecreasing with "better" lock strength. Called "Signal
169  *      Quality" in datasheets.  (Is there a standard way to measure
170  *      this?)
171  *
172  * IEEE80211_RADIOTAP_TX_ATTENUATION    __le16       unitless
173  *
174  *      Transmit power expressed as unitless distance from max
175  *      power set at factory calibration.  0 is max power.
176  *      Monotonically nondecreasing with lower power levels.
177  *
178  * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16       decibels (dB)
179  *
180  *      Transmit power expressed as decibel distance from max power
181  *      set at factory calibration.  0 is max power.  Monotonically
182  *      nondecreasing with lower power levels.
183  *
184  * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
185  *                                                   one milliwatt (dBm)
186  *
187  *      Transmit power expressed as dBm (decibels from a 1 milliwatt
188  *      reference). This is the absolute power level measured at
189  *      the antenna port.
190  *
191  * IEEE80211_RADIOTAP_FLAGS             uint8_t           bitmap
192  *
193  *      Properties of transmitted and received frames. See flags
194  *      defined below.
195  *
196  * IEEE80211_RADIOTAP_ANTENNA           uint8_t           antenna index
197  *
198  *      Unitless indication of the Rx/Tx antenna for this packet.
199  *      The first antenna is antenna 0.
200  *
201  * IEEE80211_RADIOTAP_RX_FLAGS          __le16       bitmap
202  *
203  *     Properties of received frames. See flags defined below.
204  *
205  * IEEE80211_RADIOTAP_TX_FLAGS          __le16       bitmap
206  *
207  *     Properties of transmitted frames. See flags defined below.
208  *
209  * IEEE80211_RADIOTAP_RTS_RETRIES       uint8_t           data
210  *
211  *     Number of rts retries a transmitted frame used.
212  *
213  * IEEE80211_RADIOTAP_DATA_RETRIES      uint8_t           data
214  *
215  *     Number of unicast retries a transmitted frame used.
216  *
217  */
218 enum ieee80211_radiotap_type
219 {
220   IEEE80211_RADIOTAP_TSFT = 0,
221   IEEE80211_RADIOTAP_FLAGS = 1,
222   IEEE80211_RADIOTAP_RATE = 2,
223   IEEE80211_RADIOTAP_CHANNEL = 3,
224   IEEE80211_RADIOTAP_FHSS = 4,
225   IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
226   IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
227   IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
228   IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
229   IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
230   IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
231   IEEE80211_RADIOTAP_ANTENNA = 11,
232   IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
233   IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
234   IEEE80211_RADIOTAP_RX_FLAGS = 14,
235   IEEE80211_RADIOTAP_TX_FLAGS = 15,
236   IEEE80211_RADIOTAP_RTS_RETRIES = 16,
237   IEEE80211_RADIOTAP_DATA_RETRIES = 17,
238   IEEE80211_RADIOTAP_EXT = 31
239 };
240
241 /* For IEEE80211_RADIOTAP_FLAGS */
242 #define IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
243                                                  * during CFP
244                                                  */
245 #define IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
246                                                  * with short
247                                                  * preamble
248                                                  */
249 #define IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
250                                                  * with WEP encryption
251                                                  */
252 #define IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
253                                                  * with fragmentation
254                                                  */
255 #define IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
256 #define IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
257                                                  * 802.11 header and payload
258                                                  * (to 32-bit boundary)
259                                                  */
260 /* For IEEE80211_RADIOTAP_RX_FLAGS */
261 #define IEEE80211_RADIOTAP_F_RX_BADFCS  0x0001  /* frame failed crc check */
262
263 /* For IEEE80211_RADIOTAP_TX_FLAGS */
264 #define IEEE80211_RADIOTAP_F_TX_FAIL    0x0001  /* failed due to excessive
265                                                  * retries */
266 #define IEEE80211_RADIOTAP_F_TX_CTS     0x0002  /* used cts 'protection' */
267 #define IEEE80211_RADIOTAP_F_TX_RTS     0x0004  /* used rts/cts handshake */
268 #define IEEE80211_RADIOTAP_F_TX_NOACK   0x0008  /* frame should not be ACKed */
269 #define IEEE80211_RADIOTAP_F_TX_NOSEQ   0x0010  /* sequence number handled
270                                                  * by userspace */
271
272
273 /**
274  * A generic radio capture format is desirable. There is one for
275  * Linux, but it is neither rigidly defined (there were not even
276  * units given for some fields) nor easily extensible.
277  *
278  * I suggest the following extensible radio capture format. It is
279  * based on a bitmap indicating which fields are present.
280  *
281  * I am trying to describe precisely what the application programmer
282  * should expect in the following, and for that reason I tell the
283  * units and origin of each measurement (where it applies), or else I
284  * use sufficiently weaselly language ("is a monotonically nondecreasing
285  * function of...") that I cannot set false expectations for lawyerly
286  * readers.
287  *
288  * The radio capture header precedes the 802.11 header.
289  * All data in the header is little endian on all platforms.
290  */
291 struct ieee80211_radiotap_header
292 {
293   /**
294    * Version 0. Only increases for drastic changes, introduction of
295    * compatible new fields does not count.
296    */
297   uint8_t it_version;
298   uint8_t it_pad;
299
300   /**
301    * length of the whole header in bytes, including it_version,
302    * it_pad, it_len, and data fields.
303    */
304   uint16_t it_len;
305
306   /**
307    * A bitmap telling which fields are present. Set bit 31
308    * (0x80000000) to extend the bitmap by another 32 bits.  Additional
309    * extensions are made by setting bit 31.
310    */
311   uint32_t it_present;
312 };
313
314 struct RadioTapheader
315 {
316   struct ieee80211_radiotap_header header;
317   uint8_t rate;
318   uint8_t pad1;
319   uint16_t txflags;
320 };
321
322
323 /**
324  * FIXME.
325  */
326 struct sendbuf
327 {
328   unsigned int pos;
329   unsigned int size;
330   char buf[MAXLINE * 2];
331 };
332
333
334 /**
335  * generic definitions for IEEE 802.11 frames
336  */
337 struct ieee80211_frame
338 {
339   uint8_t i_fc[2];
340   uint8_t i_dur[2];
341   uint8_t i_addr1[IEEE80211_ADDR_LEN];
342   uint8_t i_addr2[IEEE80211_ADDR_LEN];
343   uint8_t i_addr3[IEEE80211_ADDR_LEN];
344   uint8_t i_seq[2];
345   /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
346   /* see below */
347 } GNUNET_PACKED;
348
349
350 /**
351  * struct for storing the information of the hardware
352  */
353 struct Hardware_Infos
354 {
355
356   /**
357   * send buffer
358   */
359   struct sendbuf write_pout;
360   /**
361    * file descriptor for the raw socket
362    */
363   int fd_raw;
364
365   int arptype_in;
366
367   /**
368    * Name of the interface, not necessarily 0-terminated (!).
369    */
370   char iface[IFNAMSIZ];
371
372   struct MacAddress pl_mac;
373 };
374
375
376
377
378  /* *INDENT-OFF* */
379 #define ___my_swab16(x) \
380 ((u_int16_t)( \
381   (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \
382   (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) ))
383
384 #define ___my_swab32(x) \
385 ((u_int32_t)( \
386   (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \
387   (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) <<  8) | \
388   (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >>  8) | \
389   (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) ))
390 #define ___my_swab64(x) \
391 ((u_int64_t)( \
392   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \
393   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \
394   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \
395   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) <<  8) | \
396   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >>  8) | \
397   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \
398   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \
399   (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) ))
400  /* *INDENT-ON* */
401
402 #ifndef htole16
403 #if __BYTE_ORDER == __LITTLE_ENDIAN
404 #define htole16(x) (x)
405 #define le16toh(x) (x)
406 #define htole32(x) (x)
407 #define le32toh(x) (x)
408 #define htole64(x) (x)
409 #define le64toh(x) (x)
410 #else
411 #define htole16(x) ___my_swab16 (x)
412 #define le16toh(x) ___my_swab16 (x)
413 #define htole32(x) ___my_swab32 (x)
414 #define le32toh(x) ___my_swab32 (x)
415 #define htole64(x) ___my_swab64 (x)
416 #define le64toh(x) ___my_swab64 (x)
417 #endif
418 #endif
419
420
421 /**
422  * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
423  * @rtheader: pointer to the radiotap header we are walking through
424  * @max_length: length of radiotap header in cpu byte ordering
425  * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
426  * @this_arg: pointer to current radiotap arg
427  * @arg_index: internal next argument index
428  * @arg: internal next argument pointer
429  * @next_bitmap: internal pointer to next present uint32_t
430  * @bitmap_shifter: internal shifter for curr uint32_t bitmap, b0 set == arg present
431  */
432 struct ieee80211_radiotap_iterator
433 {
434   struct ieee80211_radiotap_header *rtheader;
435   int max_length;
436   int this_arg_index;
437   uint8_t *this_arg;
438   int arg_index;
439   uint8_t *arg;
440   uint32_t *next_bitmap;
441   uint32_t bitmap_shifter;
442 };
443
444
445 /**
446  * Radiotap header iteration
447  *
448  * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
449  * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
450  * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
451  * if there are no more args in the header, or the next argument type index
452  * that is present.  The iterator's this_arg member points to the start of the
453  * argument associated with the current argument index that is present,
454  * which can be found in the iterator's this_arg_index member.  This arg
455  * index corresponds to the IEEE80211_RADIOTAP_... defines.
456  */
457 static int
458 ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator
459                                   *iterator,
460                                   struct ieee80211_radiotap_header
461                                   *radiotap_header, int max_length)
462 {
463   if (iterator == NULL)
464     return (-EINVAL);
465
466   if (radiotap_header == NULL)
467     return (-EINVAL);
468   /* Linux only supports version 0 radiotap format */
469
470   if (radiotap_header->it_version)
471     return (-EINVAL);
472
473   /* sanity check for allowed length and radiotap length field */
474
475   if (max_length < (le16toh (radiotap_header->it_len)))
476     return (-EINVAL);
477
478   iterator->rtheader = radiotap_header;
479   iterator->max_length = le16toh (radiotap_header->it_len);
480   iterator->arg_index = 0;
481   iterator->bitmap_shifter = le32toh (radiotap_header->it_present);
482   iterator->arg =
483     ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
484   iterator->this_arg = 0;
485
486   /* find payload start allowing for extended bitmap(s) */
487
488   if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
489     {
490       while (le32toh (*((uint32_t *) iterator->arg)) &
491              IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
492         {
493           iterator->arg += sizeof (uint32_t);
494
495           /*
496            * check for insanity where the present bitmaps
497            * keep claiming to extend up to or even beyond the
498            * stated radiotap header length
499            */
500
501           if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
502               iterator->max_length)
503             return (-EINVAL);
504
505         }
506
507       iterator->arg += sizeof (uint32_t);
508
509       /*
510        * no need to check again for blowing past stated radiotap
511        * header length, becuase ieee80211_radiotap_iterator_next
512        * checks it before it is dereferenced
513        */
514
515     }
516
517   /* we are all initialized happily */
518   return 0;
519 }
520
521
522 /**
523  * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
524  * @iterator: radiotap_iterator to move to next arg (if any)
525  *
526  * Returns: next present arg index on success or negative if no more or error
527  *
528  * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
529  * and sets iterator->this_arg to point to the payload for the arg.  It takes
530  * care of alignment handling and extended present fields.  interator->this_arg
531  * can be changed by the caller.  The args pointed to are in little-endian
532  * format.
533  */
534 static int
535 ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator
536                                   *iterator)
537 {
538
539   /*
540    * small length lookup table for all radiotap types we heard of
541    * starting from b0 in the bitmap, so we can walk the payload
542    * area of the radiotap header
543    *
544    * There is a requirement to pad args, so that args
545    * of a given length must begin at a boundary of that length
546    * -- but note that compound args are allowed (eg, 2 x uint16_t
547    * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
548    * a reliable indicator of alignment requirement.
549    *
550    * upper nybble: content alignment for arg
551    * lower nybble: content length for arg
552    */
553
554   static const uint8_t rt_sizes[] = {
555     [IEEE80211_RADIOTAP_TSFT] = 0x88,
556     [IEEE80211_RADIOTAP_FLAGS] = 0x11,
557     [IEEE80211_RADIOTAP_RATE] = 0x11,
558     [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
559     [IEEE80211_RADIOTAP_FHSS] = 0x22,
560     [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
561     [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
562     [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
563     [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
564     [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
565     [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
566     [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
567     [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
568     [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
569     [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
570     [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
571     [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
572     [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
573       /*
574        * add more here as they are defined in
575        * include/net/ieee80211_radiotap.h
576        */
577   };
578
579   /*
580    * for every radiotap entry we can at
581    * least skip (by knowing the length)...
582    */
583
584   while (iterator->arg_index < (int) sizeof (rt_sizes))
585     {
586       int hit = 0;
587
588       if (!(iterator->bitmap_shifter & 1))
589         goto next_entry;        /* arg not present */
590
591       /*
592        * arg is present, account for alignment padding
593        *  8-bit args can be at any alignment
594        * 16-bit args must start on 16-bit boundary
595        * 32-bit args must start on 32-bit boundary
596        * 64-bit args must start on 64-bit boundary
597        *
598        * note that total arg size can differ from alignment of
599        * elements inside arg, so we use upper nybble of length
600        * table to base alignment on
601        *
602        * also note: these alignments are ** relative to the
603        * start of the radiotap header **.  There is no guarantee
604        * that the radiotap header itself is aligned on any
605        * kind of boundary.
606        */
607
608       if ((((void *) iterator->arg) -
609            ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
610                                               4) - 1))
611         iterator->arg_index +=
612           (rt_sizes[iterator->arg_index] >> 4) -
613           ((((void *) iterator->arg) -
614             ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index]
615                                                >> 4) - 1));
616
617       /*
618        * this is what we will return to user, but we need to
619        * move on first so next call has something fresh to test
620        */
621
622       iterator->this_arg_index = iterator->arg_index;
623       iterator->this_arg = iterator->arg;
624       hit = 1;
625
626       /* internally move on the size of this arg */
627
628       iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
629
630       /*
631        * check for insanity where we are given a bitmap that
632        * claims to have more arg content than the length of the
633        * radiotap section.  We will normally end up equalling this
634        * max_length on the last arg, never exceeding it.
635        */
636
637       if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
638           iterator->max_length)
639         return (-EINVAL);
640
641     next_entry:
642
643       iterator->arg_index++;
644       if (((iterator->arg_index & 31) == 0))
645         {
646           /* completed current uint32_t bitmap */
647           if (iterator->bitmap_shifter & 1)
648             {
649               /* b31 was set, there is more */
650               /* move to next uint32_t bitmap */
651               iterator->bitmap_shifter = le32toh (*iterator->next_bitmap);
652               iterator->next_bitmap++;
653             }
654           else
655             {
656               /* no more bitmaps: end */
657               iterator->arg_index = sizeof (rt_sizes);
658             }
659         }
660       else
661         {                       /* just try the next bit */
662           iterator->bitmap_shifter >>= 1;
663         }
664
665       /* if we found a valid arg earlier, return it now */
666
667       if (hit)
668         return (iterator->this_arg_index);
669
670     }
671
672   /* we don't know how to handle any more args, we're done */
673
674   return (-1);
675 }
676
677
678 /**
679  * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
680  * @param buffer pointer to buffer for the message
681  * @param mac pointer to the mac address
682  * @return number of bytes written
683  */
684 static int
685 send_mac_to_plugin (char *buffer, struct MacAddress *mac)
686 {
687
688   struct Wlan_Helper_Control_Message macmsg;
689
690   memcpy (&macmsg.mac, (char *) mac, sizeof (struct MacAddress));
691   macmsg.hdr.size = htons (sizeof (struct Wlan_Helper_Control_Message));
692   macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
693
694   memcpy (buffer, &macmsg, sizeof (struct Wlan_Helper_Control_Message));
695   return sizeof (struct Wlan_Helper_Control_Message);
696 }
697
698
699 /**
700  * Return the channel from the frequency (in Mhz)
701  * @param frequency of the channel
702  * @return number of the channel
703  */
704 static int
705 getChannelFromFrequency (int frequency)
706 {
707   if (frequency >= 2412 && frequency <= 2472)
708     return (frequency - 2407) / 5;
709   else if (frequency == 2484)
710     return 14;
711   else if (frequency >= 5000 && frequency <= 6100)
712     return (frequency - 5000) / 5;
713   else
714     return -1;
715 }
716
717
718 /**
719  * function to calculate the crc, the start of the calculation
720  * @param buf buffer to calc the crc
721  * @param len len of the buffer
722  * @return crc sum
723  */
724 static unsigned long
725 calc_crc_osdep (const unsigned char *buf, size_t len)
726 {
727   static const unsigned long int crc_tbl_osdep[256] = {
728     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
729     0xE963A535, 0x9E6495A3,
730     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
731     0xE7B82D07, 0x90BF1D91,
732     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
733     0xF4D4B551, 0x83D385C7,
734     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
735     0xFA0F3D63, 0x8D080DF5,
736     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
737     0xD20D85FD, 0xA50AB56B,
738     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
739     0xDCD60DCF, 0xABD13D59,
740     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
741     0xCFBA9599, 0xB8BDA50F,
742     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
743     0xC1611DAB, 0xB6662D3D,
744     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
745     0x9FBFE4A5, 0xE8B8D433,
746     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
747     0x91646C97, 0xE6635C01,
748     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
749     0x8208F4C1, 0xF50FC457,
750     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
751     0x8CD37CF3, 0xFBD44C65,
752     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
753     0xA4D1C46D, 0xD3D6F4FB,
754     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
755     0xAA0A4C5F, 0xDD0D7CC9,
756     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
757     0xB966D409, 0xCE61E49F,
758     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
759     0xB7BD5C3B, 0xC0BA6CAD,
760     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
761     0x04DB2615, 0x73DC1683,
762     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
763     0x0A00AE27, 0x7D079EB1,
764     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
765     0x196C3671, 0x6E6B06E7,
766     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
767     0x17B7BE43, 0x60B08ED5,
768     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
769     0x3FB506DD, 0x48B2364B,
770     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
771     0x316E8EEF, 0x4669BE79,
772     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
773     0x220216B9, 0x5505262F,
774     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
775     0x2CD99E8B, 0x5BDEAE1D,
776     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
777     0x72076785, 0x05005713,
778     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
779     0x7CDCEFB7, 0x0BDBDF21,
780     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
781     0x6FB077E1, 0x18B74777,
782     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
783     0x616BFFD3, 0x166CCF45,
784     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
785     0x4969474D, 0x3E6E77DB,
786     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
787     0x47B2CF7F, 0x30B5FFE9,
788     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
789     0x54DE5729, 0x23D967BF,
790     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
791     0x5A05DF1B, 0x2D02EF8D
792   };
793
794   unsigned long crc = 0xFFFFFFFF;
795
796   for (; len > 0; len--, buf++)
797     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
798
799   return (~crc);
800 }
801
802
803 /**
804  * Function to check crc of the wlan packet
805  * @param buf buffer of the packet
806  * @param len len of the data
807  * @return crc sum of the data
808  */
809 static int
810 check_crc_buf_osdep (const unsigned char *buf, size_t len)
811 {
812   unsigned long crc;
813
814   if (0 > len)
815     return 0;
816
817   crc = calc_crc_osdep (buf, len);
818   buf += len;
819   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
820           ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
821 }
822
823
824 /**
825  * function to get the channel of a specific wlan card
826  * @param dev pointer to the dev struct of the card
827  * @return channel number
828  */
829 static int
830 linux_get_channel (const struct Hardware_Infos *dev)
831 {
832   struct iwreq wrq;
833   int fd;
834   int frequency;
835   int chan;
836
837   memset (&wrq, 0, sizeof (struct iwreq));
838
839   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
840
841   fd = dev->fd_raw;
842   if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
843     return (-1);
844
845   frequency = wrq.u.freq.m;
846   if (100000000 < frequency)
847     frequency /= 100000;
848   else if (1000000 < frequency)
849     frequency /= 1000;
850
851   if (1000 < frequency)
852     chan = getChannelFromFrequency (frequency);
853   else
854     chan = frequency;
855
856   return chan;
857 }
858
859
860 /**
861  * function to read from a wlan card
862  * @param dev pointer to the struct of the wlan card
863  * @param buf buffer to read to
864  * @param buf_size size of the buffer
865  * @param ri radiotap_rx info
866  * @return size read from the buffer
867  */
868 static ssize_t
869 linux_read (struct Hardware_Infos *dev, unsigned char *buf,
870             size_t buf_size, struct Radiotap_rx *ri)
871 {
872   unsigned char tmpbuf[buf_size];
873   ssize_t caplen;
874   int n, got_signal, got_noise, got_channel, fcs_removed;
875
876   n = got_signal = got_noise = got_channel = fcs_removed = 0;
877
878   caplen = read (dev->fd_raw, tmpbuf, buf_size);
879   if (0 > caplen)
880     {
881       if (EAGAIN == errno)
882         return 0;
883       fprintf (stderr, "Failed to read from RAW socket: %s\n",
884                strerror (errno));
885       return -1;
886     }
887
888   memset (buf, 0, buf_size);
889   memset (ri, 0, sizeof (*ri));
890
891   switch (dev->arptype_in)
892     {
893     case ARPHRD_IEEE80211_PRISM:
894       {
895         /* skip the prism header */
896         if (tmpbuf[7] == 0x40)
897           {
898             /* prism54 uses a different format */
899             ri->ri_power = tmpbuf[0x33];
900             ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
901             ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
902             got_signal = 1;
903             got_noise = 1;
904             n = 0x40;
905           }
906         else
907           {
908             ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48);
909             ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
910             ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
911             ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
912             ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
913             got_channel = 1;
914             got_signal = 1;
915             got_noise = 1;
916             n = *(int *) (tmpbuf + 4);
917           }
918
919         if (n < 8 || n >= caplen)
920           return (0);
921       }
922       break;
923
924     case ARPHRD_IEEE80211_FULL:
925       {
926         struct ieee80211_radiotap_iterator iterator;
927         struct ieee80211_radiotap_header *rthdr;
928
929         rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
930
931         if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
932           return (0);
933
934         /* go through the radiotap arguments we have been given
935          * by the driver
936          */
937
938         while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
939           {
940
941             switch (iterator.this_arg_index)
942               {
943
944               case IEEE80211_RADIOTAP_TSFT:
945                 ri->ri_mactime = le64toh (*((uint64_t *) iterator.this_arg));
946                 break;
947
948               case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
949                 if (!got_signal)
950                   {
951                     if (*iterator.this_arg < 127)
952                       ri->ri_power = *iterator.this_arg;
953                     else
954                       ri->ri_power = *iterator.this_arg - 255;
955
956                     got_signal = 1;
957                   }
958                 break;
959
960               case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
961                 if (!got_signal)
962                   {
963                     if (*iterator.this_arg < 127)
964                       ri->ri_power = *iterator.this_arg;
965                     else
966                       ri->ri_power = *iterator.this_arg - 255;
967
968                     got_signal = 1;
969                   }
970                 break;
971
972               case IEEE80211_RADIOTAP_DBM_ANTNOISE:
973                 if (!got_noise)
974                   {
975                     if (*iterator.this_arg < 127)
976                       ri->ri_noise = *iterator.this_arg;
977                     else
978                       ri->ri_noise = *iterator.this_arg - 255;
979
980                     got_noise = 1;
981                   }
982                 break;
983
984               case IEEE80211_RADIOTAP_DB_ANTNOISE:
985                 if (!got_noise)
986                   {
987                     if (*iterator.this_arg < 127)
988                       ri->ri_noise = *iterator.this_arg;
989                     else
990                       ri->ri_noise = *iterator.this_arg - 255;
991
992                     got_noise = 1;
993                   }
994                 break;
995
996               case IEEE80211_RADIOTAP_ANTENNA:
997                 ri->ri_antenna = *iterator.this_arg;
998                 break;
999
1000               case IEEE80211_RADIOTAP_CHANNEL:
1001                 ri->ri_channel = *iterator.this_arg;
1002                 got_channel = 1;
1003                 break;
1004
1005               case IEEE80211_RADIOTAP_RATE:
1006                 ri->ri_rate = (*iterator.this_arg) * 500000;
1007                 break;
1008
1009               case IEEE80211_RADIOTAP_FLAGS:
1010                 /* is the CRC visible at the end?
1011                  * remove
1012                  */
1013                 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1014                   {
1015                     fcs_removed = 1;
1016                     caplen -= 4;
1017                   }
1018
1019                 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1020                   return (0);
1021
1022                 break;
1023               }
1024           }
1025         n = le16toh (rthdr->it_len);
1026         if (n <= 0 || n >= caplen)
1027           return 0;
1028       }
1029       break;
1030     case ARPHRD_IEEE80211:
1031       /* do nothing? */
1032       break;
1033     default:
1034       errno = ENOTSUP;
1035       return -1;
1036     }
1037
1038   caplen -= n;
1039
1040   //detect fcs at the end, even if the flag wasn't set and remove it
1041   if ((0 == fcs_removed)
1042       && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
1043     {
1044       caplen -= 4;
1045     }
1046   memcpy (buf, tmpbuf + n, caplen);
1047   if (!got_channel)
1048     ri->ri_channel = linux_get_channel (dev);
1049
1050   return caplen;
1051 }
1052
1053
1054 /**
1055  * function to open the device for read/write
1056  * @param dev pointer to the device struct
1057  * @return 0 on success
1058  */
1059 static int
1060 openraw (struct Hardware_Infos *dev)
1061 {
1062   struct ifreq ifr;
1063   struct iwreq wrq;
1064   struct packet_mreq mr;
1065   struct sockaddr_ll sll;
1066
1067   /* find the interface index */
1068   memset (&ifr, 0, sizeof (ifr));
1069   strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1070   if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1071     {
1072       fprintf (stderr,
1073                "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1074                IFNAMSIZ, dev->iface, strerror (errno));
1075       return 1;
1076     }
1077
1078   /* lookup the hardware type */
1079   memset (&sll, 0, sizeof (sll));
1080   sll.sll_family = AF_PACKET;
1081   sll.sll_ifindex = ifr.ifr_ifindex;
1082   sll.sll_protocol = htons (ETH_P_ALL);
1083   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1084     {
1085       fprintf (stderr,
1086                "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1087                IFNAMSIZ, dev->iface, strerror (errno));
1088       return 1;
1089     }
1090
1091   /* lookup iw mode */
1092   memset (&wrq, 0, sizeof (struct iwreq));
1093   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1094   if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1095     {
1096       /* most probably not supported (ie for rtap ipw interface) *
1097        * so just assume its correctly set...                     */
1098       wrq.u.mode = IW_MODE_MONITOR;
1099     }
1100
1101   if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1102        (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1103        (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
1104       (wrq.u.mode != IW_MODE_MONITOR))
1105     {
1106       fprintf (stderr,
1107                "Error: interface `%.*s' is not in monitor mode\n",
1108                IFNAMSIZ, dev->iface);
1109       return 1;
1110     }
1111
1112   /* Is interface st to up, broadcast & running ? */
1113   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1114     {
1115       /* Bring interface up */
1116       ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1117
1118       if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1119         {
1120           fprintf (stderr,
1121                    "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1122                    IFNAMSIZ, dev->iface, strerror (errno));
1123           return 1;
1124         }
1125     }
1126
1127   /* bind the raw socket to the interface */
1128   if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1129     {
1130       fprintf (stderr,
1131                "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1132                dev->iface, strerror (errno));
1133       return 1;
1134     }
1135
1136   /* lookup the hardware type */
1137   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1138     {
1139       fprintf (stderr,
1140                "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1141                IFNAMSIZ, dev->iface, strerror (errno));
1142       return 1;
1143     }
1144
1145   memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1146   dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1147   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1148       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1149       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1150     {
1151       fprintf (stderr,
1152                "Unsupported hardware link type %d on interface `%.*s'\n",
1153                ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1154       return 1;
1155     }
1156
1157   /* enable promiscuous mode */
1158   memset (&mr, 0, sizeof (mr));
1159   mr.mr_ifindex = sll.sll_ifindex;
1160   mr.mr_type = PACKET_MR_PROMISC;
1161   if (0 !=
1162       setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1163                   sizeof (mr)))
1164     {
1165       fprintf (stderr,
1166                "Failed to enable promiscuous mode on interface `%.*s'\n",
1167                IFNAMSIZ, dev->iface);
1168       return 1;
1169     }
1170
1171   return 0;
1172 }
1173
1174
1175 /**
1176  * function to prepare the helper, e.g. sockets, device...
1177  * @param dev struct for the device
1178  * @param iface name of the interface
1179  * @return 0 on success
1180  */
1181 static int
1182 wlaninit (struct Hardware_Infos *dev, const char *iface)
1183 {
1184   char strbuf[512];
1185   struct stat sbuf;
1186   int ret;
1187
1188   dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1189   if (0 > dev->fd_raw)
1190     {
1191       fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
1192       return 1;
1193     }
1194   if (dev->fd_raw >= FD_SETSIZE)
1195     {
1196       fprintf (stderr,
1197                "File descriptor too large for select (%d > %d)\n",
1198                dev->fd_raw, FD_SETSIZE);
1199       close (dev->fd_raw);
1200       return 1;
1201     }
1202
1203   /* mac80211 stack detection */
1204   ret =
1205     snprintf (strbuf,
1206               sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", iface);
1207   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1208     {
1209       fprintf (stderr,
1210                "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1211       close (dev->fd_raw);
1212       return 1;
1213     }
1214   strncpy (dev->iface, iface, IFNAMSIZ);
1215   if (0 != openraw (dev))
1216     {
1217       close (dev->fd_raw);
1218       return 1;
1219     }
1220   return 0;
1221 }
1222
1223
1224 /**
1225  * Function to test incoming packets mac for being our own.
1226  *
1227  * @param uint8_taIeeeHeader buffer of the packet
1228  * @param dev the Hardware_Infos struct
1229  * @return 0 if mac belongs to us, 1 if mac is for another target
1230  */
1231 static int
1232 mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1233           const struct Hardware_Infos *dev)
1234 {
1235   if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
1236     return 1;
1237   if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1238     return 0;
1239   if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
1240     return 0;
1241   return 1;
1242 }
1243
1244
1245 /**
1246  * function to set the wlan header to make attacks more difficult
1247  * @param uint8_taIeeeHeader pointer to the header of the packet
1248  * @param dev pointer to the Hardware_Infos struct
1249  */
1250 static void
1251 mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1252          const struct Hardware_Infos *dev)
1253 {
1254   uint8_taIeeeHeader->i_fc[0] = 0x08;
1255   uint8_taIeeeHeader->i_fc[1] = 0x00;
1256   memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE);
1257   memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
1258 }
1259
1260
1261 /**
1262  * function to process the data from the stdin
1263  * @param cls pointer to the device struct
1264  * @param client not used
1265  * @param hdr pointer to the start of the packet
1266  */
1267 static void
1268 stdin_send_hw (void *cls, void *client,
1269                const struct GNUNET_MessageHeader *hdr)
1270 {
1271   struct Hardware_Infos *dev = cls;
1272   struct sendbuf *write_pout = &dev->write_pout;
1273   struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
1274   struct ieee80211_frame *wlanheader;
1275   size_t sendsize;
1276   struct RadioTapheader rtheader;
1277
1278   rtheader.header.it_version = 0;
1279   rtheader.header.it_len = htole16 (0x0c);
1280   rtheader.header.it_present = htole32 (0x00008004);
1281   rtheader.rate = 0x00;
1282   rtheader.pad1 = 0x00;
1283   rtheader.txflags =
1284     htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1285
1286   /*  { 0x00, 0x00, <-- radiotap version
1287    * 0x0c, 0x00, <- radiotap header length
1288    * 0x04, 0x80, 0x00, 0x00,  <-- bitmap
1289    * 0x00,  <-- rate
1290    * 0x00,  <-- padding for natural alignment
1291    * 0x18, 0x00,  <-- TX flags
1292    * }; */
1293
1294   sendsize = ntohs (hdr->size);
1295   if (sendsize <
1296       sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1297     {
1298       fprintf (stderr,
1299                "Function stdin_send_hw: malformed packet (too small)\n");
1300       exit (1);
1301     }
1302   sendsize -=
1303     sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1304
1305   if (MAXLINE < sendsize)
1306     {
1307       fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1308       exit (1);
1309     }
1310   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1311     {
1312       fprintf (stderr, "Function stdin_send: wrong packet type\n");
1313       exit (1);
1314     }
1315
1316   rtheader.header.it_len = htole16 (sizeof (rtheader));
1317   rtheader.rate = header->rate;
1318   memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
1319   memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
1320   /* payload contains MAC address, but we don't trust it, so we'll
1321    * overwrite it with OUR MAC address again to prevent mischief */
1322   wlanheader =
1323     (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
1324   mac_set (wlanheader, dev);
1325   write_pout->size = sendsize + sizeof (rtheader);
1326 }
1327
1328
1329 /**
1330  * main function of the helper
1331  * @param argc number of arguments
1332  * @param argv arguments
1333  * @return 0 on success, 1 on error
1334  */
1335 int
1336 main (int argc, char *argv[])
1337 {
1338   uid_t uid;
1339   struct Hardware_Infos dev;
1340   char readbuf[MAXLINE];
1341   struct sendbuf write_std;
1342   ssize_t ret;
1343   int maxfd;
1344   fd_set rfds;
1345   fd_set wfds;
1346   int retval;
1347   int stdin_open;
1348   struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
1349
1350   if (2 != argc)
1351     {
1352       fprintf (stderr,
1353                "You must specify the name of the interface as the first and only argument to this program.\n");
1354       return 1;
1355     }
1356   if (0 != wlaninit (&dev, argv[1]))
1357     return 1;
1358   uid = getuid ();
1359   if (0 != setresuid (uid, uid, uid))
1360     {
1361       fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1362       /* not critical, continue anyway */
1363     }
1364
1365   dev.write_pout.size = 0;
1366   dev.write_pout.pos = 0;
1367   stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
1368
1369   /* send mac to STDOUT first */
1370   write_std.pos = 0;
1371   write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac);
1372   stdin_open = 1;
1373
1374   while (1)
1375     {
1376       maxfd = -1;
1377       FD_ZERO (&rfds);
1378       if ((0 == dev.write_pout.size) && (1 == stdin_open))
1379         {
1380           FD_SET (STDIN_FILENO, &rfds);
1381           maxfd = MAX (maxfd, STDIN_FILENO);
1382         }
1383       if (0 == write_std.size)
1384         {
1385           FD_SET (dev.fd_raw, &rfds);
1386           maxfd = MAX (maxfd, dev.fd_raw);
1387         }
1388       FD_ZERO (&wfds);
1389       if (0 < write_std.size)
1390         {
1391           FD_SET (STDOUT_FILENO, &wfds);
1392           maxfd = MAX (maxfd, STDOUT_FILENO);
1393         }
1394       if (0 < dev.write_pout.size)
1395         {
1396           FD_SET (dev.fd_raw, &wfds);
1397           maxfd = MAX (maxfd, dev.fd_raw);
1398         }
1399       retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1400       if ((-1 == retval) && (EINTR == errno))
1401         continue;
1402       if (0 > retval)
1403         {
1404           fprintf (stderr, "select failed: %s\n", strerror (errno));
1405           break;
1406         }
1407       if (FD_ISSET (STDOUT_FILENO, &wfds))
1408         {
1409           ret =
1410             write (STDOUT_FILENO,
1411                    write_std.buf + write_std.pos,
1412                    write_std.size - write_std.pos);
1413           if (0 > ret)
1414             {
1415               fprintf (stderr,
1416                        "Failed to write to STDOUT: %s\n", strerror (errno));
1417               break;
1418             }
1419           write_std.pos += ret;
1420           if (write_std.pos == write_std.size)
1421             {
1422               write_std.pos = 0;
1423               write_std.size = 0;
1424             }
1425         }
1426       if (FD_ISSET (dev.fd_raw, &wfds))
1427         {
1428           ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
1429           if (0 > ret)
1430             {
1431               fprintf (stderr,
1432                        "Failed to write to WLAN device: %s\n",
1433                        strerror (errno));
1434               break;
1435             }
1436           dev.write_pout.pos += ret;
1437           if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
1438             {
1439               /* we should not get partial sends with packet-oriented devices... */
1440               fprintf (stderr,
1441                        "Write error, partial send: %u/%u\n",
1442                        dev.write_pout.pos, dev.write_pout.size);
1443               break;
1444             }
1445           if (dev.write_pout.pos == dev.write_pout.size)
1446             {
1447               dev.write_pout.pos = 0;
1448               dev.write_pout.size = 0;
1449             }
1450         }
1451
1452       if (FD_ISSET (STDIN_FILENO, &rfds))
1453         {
1454           ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
1455           if (0 > ret)
1456             {
1457               fprintf (stderr,
1458                        "Read error from STDIN: %s\n", strerror (errno));
1459               break;
1460             }
1461           if (0 == ret)
1462             {
1463               /* stop reading... */
1464               stdin_open = 0;
1465             }
1466           GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
1467                                      GNUNET_NO);
1468         }
1469
1470       if (FD_ISSET (dev.fd_raw, &rfds))
1471         {
1472           struct GNUNET_MessageHeader *header;
1473           struct Radiotap_rx *rxinfo;
1474           struct ieee80211_frame *datastart;
1475
1476           header = (struct GNUNET_MessageHeader *) write_std.buf;
1477           rxinfo = (struct Radiotap_rx *) &header[1];
1478           datastart = (struct ieee80211_frame *) &rxinfo[1];
1479           ret =
1480             linux_read (&dev, (unsigned char *) datastart,
1481                         sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1482                         sizeof (struct GNUNET_MessageHeader), rxinfo);
1483           if (0 > ret)
1484             {
1485               fprintf (stderr,
1486                        "Read error from raw socket: %s\n", strerror (errno));
1487               break;
1488             }
1489           if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1490             {
1491               write_std.size =
1492                 ret + sizeof (struct GNUNET_MessageHeader) +
1493                 sizeof (struct Radiotap_rx);
1494               header->size = htons (write_std.size);
1495               header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1496             }
1497         }
1498
1499     }
1500   /* Error handling, try to clean up a bit at least */
1501   GNUNET_SERVER_mst_destroy (stdin_mst);
1502   close (dev.fd_raw);
1503   return 1;                     /* we never exit 'normally' */
1504 }
1505
1506 /* end of gnunet-transport-wlan-helper.c */