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