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
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.
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.
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.
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
28 * This program serves as the mediator between the wlan interface and
33 * we use our local copy of ieee80211_radiotap.h
35 * - since we can't support extensions we don't understand
36 * - since linux does not include it in userspace headers
38 * Portions of this code were taken from the ieee80211_radiotap.h header,
41 * Copyright (c) 2003, 2004 David Young. All rights reserved.
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
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
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
70 * Modifications to fit into the linux IEEE 802.11 stack,
71 * Mike Kershaw (dragorn@kismetwireless.net)
75 * parts taken from aircrack-ng, parts changend.
78 #include <sys/socket.h>
79 #include <sys/ioctl.h>
80 #include <sys/types.h>
85 #include <netpacket/packet.h>
86 #include <linux/if_ether.h>
88 #include <linux/wireless.h>
89 #include <netinet/in.h>
90 #include <linux/if_tun.h>
98 #include <sys/param.h>
102 #include "gnunet_protocols.h"
103 #include "plugin_transport_wlan.h"
105 #define ARPHRD_IEEE80211 801
106 #define ARPHRD_IEEE80211_PRISM 802
107 #define ARPHRD_IEEE80211_FULL 803
110 * size of 802.11 address
112 #define IEEE80211_ADDR_LEN 6
115 * Maximum size of a message allowed in either direction.
120 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
123 /* Name Data type Units
124 * ---- --------- -----
126 * IEEE80211_RADIOTAP_TSFT __le64 microseconds
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.
132 * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
134 * Tx/Rx frequency in MHz, followed by flags (see below).
136 * IEEE80211_RADIOTAP_FHSS __le16 see below
138 * For frequency-hopping radios, the hop set (first byte)
139 * and pattern (second byte).
141 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s
145 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
146 * one milliwatt (dBm)
148 * RF signal power at the antenna, decibel difference from
151 * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
152 * one milliwatt (dBm)
154 * RF noise power at the antenna, decibel difference from one
157 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
159 * RF signal power at the antenna, decibel difference from an
160 * arbitrary, fixed reference.
162 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
164 * RF noise power at the antenna, decibel difference from an
165 * arbitrary, fixed reference point.
167 * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
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
174 * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
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.
180 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
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.
186 * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
187 * one milliwatt (dBm)
189 * Transmit power expressed as dBm (decibels from a 1 milliwatt
190 * reference). This is the absolute power level measured at
193 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
195 * Properties of transmitted and received frames. See flags
198 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
200 * Unitless indication of the Rx/Tx antenna for this packet.
201 * The first antenna is antenna 0.
203 * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
205 * Properties of received frames. See flags defined below.
207 * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
209 * Properties of transmitted frames. See flags defined below.
211 * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data
213 * Number of rts retries a transmitted frame used.
215 * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data
217 * Number of unicast retries a transmitted frame used.
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
243 /* For IEEE80211_RADIOTAP_FLAGS */
244 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
247 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
251 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
252 * with WEP encryption
254 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
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)
262 /* For IEEE80211_RADIOTAP_RX_FLAGS */
263 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
265 /* For IEEE80211_RADIOTAP_TX_FLAGS */
266 #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
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
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.
280 * I suggest the following extensible radio capture format. It is
281 * based on a bitmap indicating which fields are present.
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
290 * The radio capture header precedes the 802.11 header.
291 * All data in the header is little endian on all platforms.
293 struct ieee80211_radiotap_header
296 * Version 0. Only increases for drastic changes, introduction of
297 * compatible new fields does not count.
307 * length of the whole header in bytes, including it_version,
308 * it_pad, it_len, and data fields.
313 * A bitmap telling which fields are present. Set bit 31
314 * (0x80000000) to extend the bitmap by another 32 bits. Additional
315 * extensions are made by setting bit 31.
323 struct RadioTapheader
328 struct ieee80211_radiotap_header header;
348 * IO buffer used for buffering data in transit (to wireless or to stdout).
353 * How many bytes of data are stored in 'buf' for transmission right now?
354 * Data always starts at offset 0 and extends to 'size'.
359 * How many bytes that were stored in 'buf' did we already write to the
360 * destination? Always smaller than 'size'.
365 * Buffered data; twice the maximum allowed message size as we add some
368 char buf[MAXLINE * 2];
372 * Buffer for data read from stdin to be transmitted to the wirless card.
374 static struct SendBuffer write_pout;
377 * Buffer for data read from the wireless card to be transmitted to stdout.
379 static struct SendBuffer write_std;
385 * struct for storing the information of the hardware
391 * file descriptor for the raw socket
396 * Which format has the header that we're getting when receiving packets?
397 * Some ARPHRD_IEEE80211_XXX-value.
402 * Name of the interface, not necessarily 0-terminated (!).
404 char iface[IFNAMSIZ];
407 * MAC address of our own WLAN interface.
409 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
414 * struct ieee80211_radiotap_iterator - tracks walk through present radiotap arguments
415 * in the radiotap header.
417 struct ieee80211_radiotap_iterator
420 * pointer to the radiotap header we are walking through
422 const struct ieee80211_radiotap_header *rtheader;
425 * length of radiotap header in cpu byte ordering
430 * IEEE80211_RADIOTAP_... index of current arg
432 unsigned int this_arg_index;
435 * pointer to current radiotap arg
440 * internal next argument index
442 unsigned int arg_index;
445 * internal next argument pointer
450 * internal pointer to next present uint32_t
452 uint32_t *next_bitmap;
455 * internal shifter for curr uint32_t bitmap, b0 set == arg present
457 uint32_t bitmap_shifter;
462 /* specialized version of server_mst.c begins here */
464 #define ALIGN_FACTOR 8
467 * Smallest supported message.
469 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
473 * Functions with this signature are called whenever a
474 * complete message is received by the tokenizer.
477 * @param message the actual message
479 typedef void (*MessageTokenizerCallback) (void *cls,
481 GNUNET_MessageHeader *
485 * Handle to a message stream tokenizer.
487 struct MessageStreamTokenizer
491 * Function to call on completed messages.
493 MessageTokenizerCallback cb;
501 * Size of the buffer (starting at 'hdr').
506 * How many bytes in buffer have we already processed?
511 * How many bytes in buffer are valid right now?
516 * Beginning of the buffer. Typed like this to force alignment.
518 struct GNUNET_MessageHeader *hdr;
525 * Create a message stream tokenizer.
527 * @param cb function to call on completed messages
528 * @param cb_cls closure for cb
529 * @return handle to tokenizer
531 static struct MessageStreamTokenizer *
532 mst_create (MessageTokenizerCallback cb,
535 struct MessageStreamTokenizer *ret;
537 ret = malloc (sizeof (struct MessageStreamTokenizer));
540 ret->hdr = malloc (MIN_BUFFER_SIZE);
541 if (NULL == ret->hdr)
543 ret->curr_buf = MIN_BUFFER_SIZE;
545 ret->cb_cls = cb_cls;
551 * Add incoming data to the receive buffer and call the
552 * callback for all complete messages.
554 * @param mst tokenizer to use
555 * @param buf input data to add
556 * @param size number of bytes in buf
557 * @return GNUNET_OK if we are done processing (need more data)
558 * GNUNET_SYSERR if the data stream is corrupt
561 mst_receive (struct MessageStreamTokenizer *mst,
562 const char *buf, size_t size)
564 const struct GNUNET_MessageHeader *hdr;
569 unsigned long offset;
573 ibuf = (char *) mst->hdr;
577 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
578 (0 != (mst->off % ALIGN_FACTOR)))
580 /* need to align or need more space */
581 mst->pos -= mst->off;
582 memmove (ibuf, &ibuf[mst->off], mst->pos);
585 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
588 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
589 (mst->pos - mst->off), size);
590 memcpy (&ibuf[mst->pos], buf, delta);
595 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
599 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
600 want = ntohs (hdr->size);
601 if (want < sizeof (struct GNUNET_MessageHeader))
603 // GNUNET_break_op (0);
604 return GNUNET_SYSERR;
606 if (mst->curr_buf - mst->off < want)
608 /* need more space */
609 mst->pos -= mst->off;
610 memmove (ibuf, &ibuf[mst->off], mst->pos);
613 if (want > mst->curr_buf)
615 mst->hdr = realloc (mst->hdr, want);
616 if (NULL == mst->hdr)
618 ibuf = (char *) mst->hdr;
619 mst->curr_buf = want;
621 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
622 if (mst->pos - mst->off < want)
624 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
625 memcpy (&ibuf[mst->pos], buf, delta);
630 if (mst->pos - mst->off < want)
634 mst->cb (mst->cb_cls, hdr);
636 if (mst->off == mst->pos)
638 /* reset to beginning of buffer, it's free right now! */
645 if (size < sizeof (struct GNUNET_MessageHeader))
647 offset = (unsigned long) buf;
648 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
649 if (GNUNET_NO == need_align)
651 /* can try to do zero-copy and process directly from original buffer */
652 hdr = (const struct GNUNET_MessageHeader *) buf;
653 want = ntohs (hdr->size);
654 if (want < sizeof (struct GNUNET_MessageHeader))
656 // GNUNET_break_op (0);
658 return GNUNET_SYSERR;
661 break; /* or not, buffer incomplete, so copy to private buffer... */
662 mst->cb (mst->cb_cls, hdr);
668 /* need to copy to private buffer to align;
669 * yes, we go a bit more spagetti than usual here */
675 if (size + mst->pos > mst->curr_buf)
677 mst->hdr = realloc (mst->hdr, size + mst->pos);
678 if (NULL == mst->hdr)
680 ibuf = (char *) mst->hdr;
681 mst->curr_buf = size + mst->pos;
683 // GNUNET_assert (mst->pos + size <= mst->curr_buf);
684 memcpy (&ibuf[mst->pos], buf, size);
692 * Destroys a tokenizer.
694 * @param mst tokenizer to destroy
697 mst_destroy (struct MessageStreamTokenizer *mst)
703 /* end of server_mst.c copy */
709 * Radiotap header iteration
711 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
712 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
713 * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
714 * if there are no more args in the header, or the next argument type index
715 * that is present. The iterator's this_arg member points to the start of the
716 * argument associated with the current argument index that is present,
717 * which can be found in the iterator's this_arg_index member. This arg
718 * index corresponds to the IEEE80211_RADIOTAP_... defines.
720 * @param iterator iterator to initialize
721 * @param radiotap_header message to parse
722 * @param max_length number of valid bytes in radiotap_header
723 * @return 0 on success, -1 on error
726 ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
727 const struct ieee80211_radiotap_header
731 if ( (iterator == NULL) ||
732 (radiotap_header == NULL) )
735 /* Linux only supports version 0 radiotap format */
736 if (0 != radiotap_header->it_version)
739 /* sanity check for allowed length and radiotap length field */
740 if ( (max_length < sizeof (struct ieee80211_radiotap_header)) ||
741 (max_length < (GNUNET_le16toh (radiotap_header->it_len))) )
744 iterator->rtheader = radiotap_header;
745 iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
746 iterator->arg_index = 0;
747 iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
749 ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
750 iterator->this_arg = 0;
752 /* find payload start allowing for extended bitmap(s) */
753 if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
755 while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
756 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
758 iterator->arg += sizeof (uint32_t);
761 * check for insanity where the present bitmaps
762 * keep claiming to extend up to or even beyond the
763 * stated radiotap header length
765 if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
768 iterator->arg += sizeof (uint32_t);
770 * no need to check again for blowing past stated radiotap
771 * header length, becuase ieee80211_radiotap_iterator_next
772 * checks it before it is dereferenced
775 /* we are all initialized happily */
781 * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
783 * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
784 * and sets iterator->this_arg to point to the payload for the arg. It takes
785 * care of alignment handling and extended present fields. interator->this_arg
786 * can be changed by the caller. The args pointed to are in little-endian
789 * @param iterator: radiotap_iterator to move to next arg (if any)
791 * @return next present arg index on success or -1 if no more or error
794 ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
798 * small length lookup table for all radiotap types we heard of
799 * starting from b0 in the bitmap, so we can walk the payload
800 * area of the radiotap header
802 * There is a requirement to pad args, so that args
803 * of a given length must begin at a boundary of that length
804 * -- but note that compound args are allowed (eg, 2 x uint16_t
805 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
806 * a reliable indicator of alignment requirement.
808 * upper nybble: content alignment for arg
809 * lower nybble: content length for arg
812 static const uint8_t rt_sizes[] = {
813 [IEEE80211_RADIOTAP_TSFT] = 0x88,
814 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
815 [IEEE80211_RADIOTAP_RATE] = 0x11,
816 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
817 [IEEE80211_RADIOTAP_FHSS] = 0x22,
818 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
819 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
820 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
821 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
822 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
823 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
824 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
825 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
826 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
827 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
828 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
829 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
830 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
832 * add more here as they are defined in
833 * include/net/ieee80211_radiotap.h
838 * for every radiotap entry we can at
839 * least skip (by knowing the length)...
842 while (iterator->arg_index < sizeof (rt_sizes))
846 if (!(iterator->bitmap_shifter & 1))
847 goto next_entry; /* arg not present */
850 * arg is present, account for alignment padding
851 * 8-bit args can be at any alignment
852 * 16-bit args must start on 16-bit boundary
853 * 32-bit args must start on 32-bit boundary
854 * 64-bit args must start on 64-bit boundary
856 * note that total arg size can differ from alignment of
857 * elements inside arg, so we use upper nybble of length
858 * table to base alignment on
860 * also note: these alignments are ** relative to the
861 * start of the radiotap header **. There is no guarantee
862 * that the radiotap header itself is aligned on any
866 if ((((void *) iterator->arg) -
867 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
869 iterator->arg_index +=
870 (rt_sizes[iterator->arg_index] >> 4) -
871 ((((void *) iterator->arg) -
872 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
876 * this is what we will return to user, but we need to
877 * move on first so next call has something fresh to test
880 iterator->this_arg_index = iterator->arg_index;
881 iterator->this_arg = iterator->arg;
884 /* internally move on the size of this arg */
886 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
889 * check for insanity where we are given a bitmap that
890 * claims to have more arg content than the length of the
891 * radiotap section. We will normally end up equalling this
892 * max_length on the last arg, never exceeding it.
895 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
896 iterator->max_length)
901 iterator->arg_index++;
902 if (((iterator->arg_index & 31) == 0))
904 /* completed current uint32_t bitmap */
905 if (iterator->bitmap_shifter & 1)
907 /* b31 was set, there is more */
908 /* move to next uint32_t bitmap */
909 iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
910 iterator->next_bitmap++;
914 /* no more bitmaps: end */
915 iterator->arg_index = sizeof (rt_sizes);
919 { /* just try the next bit */
920 iterator->bitmap_shifter >>= 1;
923 /* if we found a valid arg earlier, return it now */
926 return iterator->this_arg_index;
930 /* we don't know how to handle any more args, we're done */
936 * Return the channel from the frequency (in Mhz)
937 * @param frequency of the channel
938 * @return number of the channel
941 get_channel_from_frequency (int frequency)
943 if (frequency >= 2412 && frequency <= 2472)
944 return (frequency - 2407) / 5;
945 if (frequency == 2484)
947 if (frequency >= 5000 && frequency <= 6100)
948 return (frequency - 5000) / 5;
954 * function to calculate the crc, the start of the calculation
956 * @param buf buffer to calc the crc
957 * @param len len of the buffer
961 calc_crc_osdep (const unsigned char *buf, size_t len)
963 static const unsigned long int crc_tbl_osdep[256] = {
964 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
965 0xE963A535, 0x9E6495A3,
966 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
967 0xE7B82D07, 0x90BF1D91,
968 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
969 0xF4D4B551, 0x83D385C7,
970 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
971 0xFA0F3D63, 0x8D080DF5,
972 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
973 0xD20D85FD, 0xA50AB56B,
974 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
975 0xDCD60DCF, 0xABD13D59,
976 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
977 0xCFBA9599, 0xB8BDA50F,
978 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
979 0xC1611DAB, 0xB6662D3D,
980 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
981 0x9FBFE4A5, 0xE8B8D433,
982 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
983 0x91646C97, 0xE6635C01,
984 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
985 0x8208F4C1, 0xF50FC457,
986 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
987 0x8CD37CF3, 0xFBD44C65,
988 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
989 0xA4D1C46D, 0xD3D6F4FB,
990 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
991 0xAA0A4C5F, 0xDD0D7CC9,
992 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
993 0xB966D409, 0xCE61E49F,
994 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
995 0xB7BD5C3B, 0xC0BA6CAD,
996 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
997 0x04DB2615, 0x73DC1683,
998 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
999 0x0A00AE27, 0x7D079EB1,
1000 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1001 0x196C3671, 0x6E6B06E7,
1002 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1003 0x17B7BE43, 0x60B08ED5,
1004 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1005 0x3FB506DD, 0x48B2364B,
1006 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1007 0x316E8EEF, 0x4669BE79,
1008 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1009 0x220216B9, 0x5505262F,
1010 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1011 0x2CD99E8B, 0x5BDEAE1D,
1012 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1013 0x72076785, 0x05005713,
1014 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1015 0x7CDCEFB7, 0x0BDBDF21,
1016 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1017 0x6FB077E1, 0x18B74777,
1018 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1019 0x616BFFD3, 0x166CCF45,
1020 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1021 0x4969474D, 0x3E6E77DB,
1022 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1023 0x47B2CF7F, 0x30B5FFE9,
1024 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1025 0x54DE5729, 0x23D967BF,
1026 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1027 0x5A05DF1B, 0x2D02EF8D
1030 unsigned long crc = 0xFFFFFFFF;
1032 for (; len > 0; len--, buf++)
1033 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1039 * Function to calculate and check crc of the wlan packet
1041 * @param buf buffer of the packet, with len + 4 bytes of data,
1042 * the last 4 bytes being the checksum
1043 * @param len length of the payload in data
1044 * @return 0 on success (checksum matches), 1 on error
1047 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1051 crc = calc_crc_osdep (buf, len);
1053 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1054 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
1061 * Get the channel used by our WLAN interface.
1063 * @param dev pointer to the dev struct of the card
1064 * @return channel number, -1 on error
1067 linux_get_channel (const struct HardwareInfos *dev)
1074 memset (&wrq, 0, sizeof (struct iwreq));
1075 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1077 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1080 frequency = wrq.u.freq.m;
1081 if (100000000 < frequency)
1082 frequency /= 100000;
1083 else if (1000000 < frequency)
1085 if (1000 < frequency)
1086 chan = get_channel_from_frequency (frequency);
1094 * function to read from a wlan card
1095 * @param dev pointer to the struct of the wlan card
1096 * @param buf buffer to read to
1097 * @param buf_size size of the buffer
1098 * @param ri radiotap_rx info
1099 * @return size read from the buffer
1102 linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1103 struct Radiotap_rx *ri)
1105 unsigned char tmpbuf[buf_size];
1107 int n, got_signal, got_noise, got_channel, fcs_removed;
1109 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1111 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1114 if (EAGAIN == errno)
1116 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1120 memset (buf, 0, buf_size);
1121 memset (ri, 0, sizeof (*ri));
1123 switch (dev->arptype_in)
1125 case ARPHRD_IEEE80211_PRISM:
1127 /* skip the prism header */
1128 if (tmpbuf[7] == 0x40)
1130 /* prism54 uses a different format */
1131 ri->ri_power = tmpbuf[0x33];
1132 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
1133 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
1140 ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48);
1141 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
1142 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
1143 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
1144 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
1148 n = *(int *) (tmpbuf + 4);
1151 if ( (n < 8) || (n >= caplen) )
1156 case ARPHRD_IEEE80211_FULL:
1158 struct ieee80211_radiotap_iterator iterator;
1159 struct ieee80211_radiotap_header *rthdr;
1161 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1163 if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
1166 /* go through the radiotap arguments we have been given
1170 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1173 switch (iterator.this_arg_index)
1176 case IEEE80211_RADIOTAP_TSFT:
1177 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1180 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1183 if (*iterator.this_arg < 127)
1184 ri->ri_power = *iterator.this_arg;
1186 ri->ri_power = *iterator.this_arg - 255;
1192 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1195 if (*iterator.this_arg < 127)
1196 ri->ri_power = *iterator.this_arg;
1198 ri->ri_power = *iterator.this_arg - 255;
1204 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1207 if (*iterator.this_arg < 127)
1208 ri->ri_noise = *iterator.this_arg;
1210 ri->ri_noise = *iterator.this_arg - 255;
1216 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1219 if (*iterator.this_arg < 127)
1220 ri->ri_noise = *iterator.this_arg;
1222 ri->ri_noise = *iterator.this_arg - 255;
1228 case IEEE80211_RADIOTAP_ANTENNA:
1229 ri->ri_antenna = *iterator.this_arg;
1232 case IEEE80211_RADIOTAP_CHANNEL:
1233 ri->ri_channel = *iterator.this_arg;
1237 case IEEE80211_RADIOTAP_RATE:
1238 ri->ri_rate = (*iterator.this_arg) * 500000;
1241 case IEEE80211_RADIOTAP_FLAGS:
1242 /* is the CRC visible at the end?
1245 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1251 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1257 n = GNUNET_le16toh (rthdr->it_len);
1258 if (n <= 0 || n >= caplen)
1262 case ARPHRD_IEEE80211:
1272 //detect fcs at the end, even if the flag wasn't set and remove it
1273 if ((0 == fcs_removed) && (0 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
1277 memcpy (buf, tmpbuf + n, caplen);
1279 ri->ri_channel = linux_get_channel (dev);
1286 * Open the wireless network interface for reading/writing.
1288 * @param dev pointer to the device struct
1289 * @return 0 on success
1292 open_device_raw (struct HardwareInfos *dev)
1296 struct packet_mreq mr;
1297 struct sockaddr_ll sll;
1299 /* find the interface index */
1300 memset (&ifr, 0, sizeof (ifr));
1301 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1302 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1304 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1305 IFNAMSIZ, dev->iface, strerror (errno));
1309 /* lookup the hardware type */
1310 memset (&sll, 0, sizeof (sll));
1311 sll.sll_family = AF_PACKET;
1312 sll.sll_ifindex = ifr.ifr_ifindex;
1313 sll.sll_protocol = htons (ETH_P_ALL);
1314 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1316 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1317 IFNAMSIZ, dev->iface, strerror (errno));
1321 /* lookup iw mode */
1322 memset (&wrq, 0, sizeof (struct iwreq));
1323 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1324 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1326 /* most probably not supported (ie for rtap ipw interface) *
1327 * so just assume its correctly set... */
1328 wrq.u.mode = IW_MODE_MONITOR;
1331 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1332 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1333 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
1334 (wrq.u.mode != IW_MODE_MONITOR))
1336 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1337 IFNAMSIZ, dev->iface);
1341 /* Is interface st to up, broadcast & running ? */
1342 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1344 /* Bring interface up */
1345 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1347 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1349 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1350 IFNAMSIZ, dev->iface, strerror (errno));
1355 /* bind the raw socket to the interface */
1356 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1358 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1359 dev->iface, strerror (errno));
1363 /* lookup the hardware type */
1364 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1366 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1367 IFNAMSIZ, dev->iface, strerror (errno));
1371 memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1372 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1373 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1374 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1375 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1377 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1378 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1382 /* enable promiscuous mode */
1383 memset (&mr, 0, sizeof (mr));
1384 mr.mr_ifindex = sll.sll_ifindex;
1385 mr.mr_type = PACKET_MR_PROMISC;
1387 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1390 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1391 IFNAMSIZ, dev->iface);
1400 * Test if the given interface name really corresponds to a wireless
1403 * @param iface name of the interface
1404 * @return 0 on success, 1 on error
1407 test_wlan_interface (const char *iface)
1413 /* mac80211 stack detection */
1415 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1417 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1419 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1427 * Function to test incoming packets mac for being our own.
1429 * @param taIeeeHeader buffer of the packet
1430 * @param dev the Hardware_Infos struct
1431 * @return 0 if mac belongs to us, 1 if mac is for another target
1434 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1435 const struct HardwareInfos *dev)
1437 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1439 if (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1441 if (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE))
1448 * function to set the wlan header to make attacks more difficult
1449 * @param taIeeeHeader pointer to the header of the packet
1450 * @param dev pointer to the Hardware_Infos struct
1453 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1454 const struct HardwareInfos *dev)
1456 taIeeeHeader->frame_control = ntohs (0x08); // FIXME: need to shift by 8?
1457 taIeeeHeader->addr2 = dev->pl_mac;
1458 taIeeeHeader->addr3 = mac_bssid_gnunet;
1463 * function to process the data from the stdin
1464 * @param cls pointer to the device struct
1465 * @param hdr pointer to the start of the packet
1468 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1470 struct HardwareInfos *dev = cls;
1471 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1472 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
1474 struct RadioTapheader rtheader;
1476 sendsize = ntohs (hdr->size);
1478 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1479 (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) )
1481 fprintf (stderr, "Received malformed message\n");
1484 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1485 if (MAXLINE < sendsize)
1487 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1490 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1491 rtheader.header.it_version = 0; /* radiotap version */
1492 rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */
1493 rtheader.header.it_present = GNUNET_htole16 (0x00008004); /* our bitmap */
1494 rtheader.rate = 0x00;
1495 rtheader.pad1 = 0x00;
1496 rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1497 rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
1498 rtheader.rate = header->rate;
1499 memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
1500 wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
1501 memcpy (wlanheader, &header->frame, sendsize);
1502 /* payload contains MAC address, but we don't trust it, so we'll
1503 * overwrite it with OUR MAC address again to prevent mischief */
1504 mac_set (wlanheader, dev);
1505 write_pout.size = sendsize + sizeof (rtheader);
1510 * Main function of the helper. This code accesses a WLAN interface
1511 * in monitoring mode (layer 2) and then forwards traffic in both
1512 * directions between the WLAN interface and stdin/stdout of this
1513 * process. Error messages are written to stdout.
1515 * @param argc number of arguments, must be 2
1516 * @param argv arguments only argument is the name of the interface (i.e. 'mon0')
1517 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1520 main (int argc, char *argv[])
1522 struct HardwareInfos dev;
1523 char readbuf[MAXLINE];
1528 struct MessageStreamTokenizer *stdin_mst;
1531 memset (&dev, 0, sizeof (dev));
1532 dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1533 raw_eno = errno; /* remember for later */
1537 uid_t uid = getuid ();
1538 #ifdef HAVE_SETRESUID
1539 if (0 != setresuid (uid, uid, uid))
1541 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1542 if (-1 != dev.fd_raw)
1543 (void) close (dev.fd_raw);
1547 if (0 != (setuid (uid) | seteuid (uid)))
1549 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1550 if (-1 != dev.fd_raw)
1551 (void) close (dev.fd_raw);
1557 /* now that we've dropped root rights, we can do error checking */
1561 "You must specify the name of the interface as the first and only argument to this program.\n");
1562 if (-1 != dev.fd_raw)
1563 (void) close (dev.fd_raw);
1567 if (-1 == dev.fd_raw)
1569 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1572 if (dev.fd_raw >= FD_SETSIZE)
1574 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1575 dev.fd_raw, FD_SETSIZE);
1576 (void) close (dev.fd_raw);
1579 if (0 != test_wlan_interface (argv[1]))
1581 (void) close (dev.fd_raw);
1584 strncpy (dev.iface, argv[1], IFNAMSIZ);
1585 if (0 != open_device_raw (&dev))
1587 (void) close (dev.fd_raw);
1591 /* send MAC address of the WLAN interface to STDOUT first */
1593 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1595 macmsg.hdr.size = htons (sizeof (macmsg));
1596 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1597 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1598 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1599 write_std.size = sizeof (macmsg);
1602 stdin_mst = mst_create (&stdin_send_hw, &dev);
1608 if ((0 == write_pout.size) && (1 == stdin_open))
1610 FD_SET (STDIN_FILENO, &rfds);
1611 maxfd = MAX (maxfd, STDIN_FILENO);
1613 if (0 == write_std.size)
1615 FD_SET (dev.fd_raw, &rfds);
1616 maxfd = MAX (maxfd, dev.fd_raw);
1619 if (0 < write_std.size)
1621 FD_SET (STDOUT_FILENO, &wfds);
1622 maxfd = MAX (maxfd, STDOUT_FILENO);
1624 if (0 < write_pout.size)
1626 FD_SET (dev.fd_raw, &wfds);
1627 maxfd = MAX (maxfd, dev.fd_raw);
1630 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1631 if ((-1 == retval) && (EINTR == errno))
1635 fprintf (stderr, "select failed: %s\n", strerror (errno));
1639 if (FD_ISSET (STDOUT_FILENO, &wfds))
1642 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1643 write_std.size - write_std.pos);
1646 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1649 write_std.pos += ret;
1650 if (write_std.pos == write_std.size)
1656 if (FD_ISSET (dev.fd_raw, &wfds))
1659 write (dev.fd_raw, write_pout.buf + write_std.pos,
1660 write_pout.size - write_pout.pos);
1663 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1667 write_pout.pos += ret;
1668 if ((write_pout.pos != write_pout.size) && (0 != ret))
1670 /* we should not get partial sends with packet-oriented devices... */
1671 fprintf (stderr, "Write error, partial send: %u/%u\n",
1672 (unsigned int) write_pout.pos,
1673 (unsigned int) write_pout.size);
1676 if (write_pout.pos == write_pout.size)
1679 write_pout.size = 0;
1683 if (FD_ISSET (STDIN_FILENO, &rfds))
1686 read (STDIN_FILENO, readbuf, sizeof (readbuf));
1689 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1694 /* stop reading... */
1697 mst_receive (stdin_mst, readbuf, ret);
1700 if (FD_ISSET (dev.fd_raw, &rfds))
1702 struct GNUNET_MessageHeader *header;
1703 struct Radiotap_rx *rxinfo;
1704 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *datastart;
1707 header = (struct GNUNET_MessageHeader *) write_std.buf;
1708 rxinfo = (struct Radiotap_rx *) &header[1];
1709 datastart = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &rxinfo[1];
1711 linux_read (&dev, (unsigned char *) datastart,
1712 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1713 sizeof (struct GNUNET_MessageHeader), rxinfo);
1716 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1719 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1722 ret + sizeof (struct GNUNET_MessageHeader) +
1723 sizeof (struct Radiotap_rx);
1724 header->size = htons (write_std.size);
1725 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1730 /* Error handling, try to clean up a bit at least */
1731 mst_destroy (stdin_mst);
1732 (void) close (dev.fd_raw);
1733 return 1; /* we never exit 'normally' */
1736 /* end of gnunet-helper-transport-wlan.c */