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.
303 * length of the whole header in bytes, including it_version,
304 * it_pad, it_len, and data fields.
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.
319 struct RadioTapheader
324 struct ieee80211_radiotap_header header;
344 * IO buffer used for buffering data in transit (to wireless or to stdout).
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'.
355 * How many bytes that were stored in 'buf' did we already write to the
356 * destination? Always smaller than 'size'.
361 * Buffered data; twice the maximum allowed message size as we add some
364 char buf[MAXLINE * 2];
368 * Buffer for data read from stdin to be transmitted to the wirless card.
370 static struct SendBuffer write_pout;
373 * Buffer for data read from the wireless card to be transmitted to stdout.
375 static struct SendBuffer write_std;
378 GNUNET_NETWORK_STRUCT_BEGIN
381 * generic definitions for IEEE 802.11 frames
383 struct ieee80211_frame
387 uint8_t i_addr1[IEEE80211_ADDR_LEN];
388 uint8_t i_addr2[IEEE80211_ADDR_LEN];
389 uint8_t i_addr3[IEEE80211_ADDR_LEN];
391 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
394 GNUNET_NETWORK_STRUCT_END
398 * struct for storing the information of the hardware
404 * file descriptor for the raw socket
409 * Which format has the header that we're getting when receiving packets?
410 * Some ARPHRD_IEEE80211_XXX-value.
415 * Name of the interface, not necessarily 0-terminated (!).
417 char iface[IFNAMSIZ];
420 * MAC address of our own WLAN interface.
422 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
427 * struct ieee80211_radiotap_iterator - tracks walk through present radiotap arguments
428 * in the radiotap header.
430 struct ieee80211_radiotap_iterator
433 * pointer to the radiotap header we are walking through
435 const struct ieee80211_radiotap_header *rtheader;
438 * length of radiotap header in cpu byte ordering
443 * IEEE80211_RADIOTAP_... index of current arg
445 unsigned int this_arg_index;
448 * pointer to current radiotap arg
453 * internal next argument index
455 unsigned int arg_index;
458 * internal next argument pointer
463 * internal pointer to next present uint32_t
465 uint32_t *next_bitmap;
468 * internal shifter for curr uint32_t bitmap, b0 set == arg present
470 uint32_t bitmap_shifter;
475 /* specialized version of server_mst.c begins here */
477 #define ALIGN_FACTOR 8
480 * Smallest supported message.
482 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
486 * Functions with this signature are called whenever a
487 * complete message is received by the tokenizer.
490 * @param message the actual message
492 typedef void (*MessageTokenizerCallback) (void *cls,
494 GNUNET_MessageHeader *
498 * Handle to a message stream tokenizer.
500 struct MessageStreamTokenizer
504 * Function to call on completed messages.
506 MessageTokenizerCallback cb;
514 * Size of the buffer (starting at 'hdr').
519 * How many bytes in buffer have we already processed?
524 * How many bytes in buffer are valid right now?
529 * Beginning of the buffer. Typed like this to force alignment.
531 struct GNUNET_MessageHeader *hdr;
538 * Create a message stream tokenizer.
540 * @param cb function to call on completed messages
541 * @param cb_cls closure for cb
542 * @return handle to tokenizer
544 static struct MessageStreamTokenizer *
545 mst_create (MessageTokenizerCallback cb,
548 struct MessageStreamTokenizer *ret;
550 ret = malloc (sizeof (struct MessageStreamTokenizer));
553 ret->hdr = malloc (MIN_BUFFER_SIZE);
554 if (NULL == ret->hdr)
556 ret->curr_buf = MIN_BUFFER_SIZE;
558 ret->cb_cls = cb_cls;
564 * Add incoming data to the receive buffer and call the
565 * callback for all complete messages.
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
574 mst_receive (struct MessageStreamTokenizer *mst,
575 const char *buf, size_t size)
577 const struct GNUNET_MessageHeader *hdr;
582 unsigned long offset;
586 ibuf = (char *) mst->hdr;
590 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
591 (0 != (mst->off % ALIGN_FACTOR)))
593 /* need to align or need more space */
594 mst->pos -= mst->off;
595 memmove (ibuf, &ibuf[mst->off], mst->pos);
598 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
601 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
602 (mst->pos - mst->off), size);
603 memcpy (&ibuf[mst->pos], buf, delta);
608 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
612 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
613 want = ntohs (hdr->size);
614 if (want < sizeof (struct GNUNET_MessageHeader))
616 // GNUNET_break_op (0);
617 return GNUNET_SYSERR;
619 if (mst->curr_buf - mst->off < want)
621 /* need more space */
622 mst->pos -= mst->off;
623 memmove (ibuf, &ibuf[mst->off], mst->pos);
626 if (want > mst->curr_buf)
628 mst->hdr = realloc (mst->hdr, want);
629 if (NULL == mst->hdr)
631 ibuf = (char *) mst->hdr;
632 mst->curr_buf = want;
634 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
635 if (mst->pos - mst->off < want)
637 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
638 memcpy (&ibuf[mst->pos], buf, delta);
643 if (mst->pos - mst->off < want)
647 mst->cb (mst->cb_cls, hdr);
649 if (mst->off == mst->pos)
651 /* reset to beginning of buffer, it's free right now! */
658 if (size < sizeof (struct GNUNET_MessageHeader))
660 offset = (unsigned long) buf;
661 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
662 if (GNUNET_NO == need_align)
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))
669 // GNUNET_break_op (0);
671 return GNUNET_SYSERR;
674 break; /* or not, buffer incomplete, so copy to private buffer... */
675 mst->cb (mst->cb_cls, hdr);
681 /* need to copy to private buffer to align;
682 * yes, we go a bit more spagetti than usual here */
688 if (size + mst->pos > mst->curr_buf)
690 mst->hdr = realloc (mst->hdr, size + mst->pos);
691 if (NULL == mst->hdr)
693 ibuf = (char *) mst->hdr;
694 mst->curr_buf = size + mst->pos;
696 // GNUNET_assert (mst->pos + size <= mst->curr_buf);
697 memcpy (&ibuf[mst->pos], buf, size);
705 * Destroys a tokenizer.
707 * @param mst tokenizer to destroy
710 mst_destroy (struct MessageStreamTokenizer *mst)
716 /* end of server_mst.c copy */
722 * Radiotap header iteration
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.
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
739 ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
740 const struct ieee80211_radiotap_header
744 if ( (iterator == NULL) ||
745 (radiotap_header == NULL) )
748 /* Linux only supports version 0 radiotap format */
749 if (0 != radiotap_header->it_version)
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))) )
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);
762 ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
763 iterator->this_arg = 0;
765 /* find payload start allowing for extended bitmap(s) */
766 if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
768 while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
769 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
771 iterator->arg += sizeof (uint32_t);
774 * check for insanity where the present bitmaps
775 * keep claiming to extend up to or even beyond the
776 * stated radiotap header length
778 if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
781 iterator->arg += sizeof (uint32_t);
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
788 /* we are all initialized happily */
794 * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
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
802 * @param iterator: radiotap_iterator to move to next arg (if any)
804 * @return next present arg index on success or -1 if no more or error
807 ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
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
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.
821 * upper nybble: content alignment for arg
822 * lower nybble: content length for arg
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
845 * add more here as they are defined in
846 * include/net/ieee80211_radiotap.h
851 * for every radiotap entry we can at
852 * least skip (by knowing the length)...
855 while (iterator->arg_index < sizeof (rt_sizes))
859 if (!(iterator->bitmap_shifter & 1))
860 goto next_entry; /* arg not present */
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
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
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
879 if ((((void *) iterator->arg) -
880 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
882 iterator->arg_index +=
883 (rt_sizes[iterator->arg_index] >> 4) -
884 ((((void *) iterator->arg) -
885 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
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
893 iterator->this_arg_index = iterator->arg_index;
894 iterator->this_arg = iterator->arg;
897 /* internally move on the size of this arg */
899 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
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.
908 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
909 iterator->max_length)
914 iterator->arg_index++;
915 if (((iterator->arg_index & 31) == 0))
917 /* completed current uint32_t bitmap */
918 if (iterator->bitmap_shifter & 1)
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++;
927 /* no more bitmaps: end */
928 iterator->arg_index = sizeof (rt_sizes);
932 { /* just try the next bit */
933 iterator->bitmap_shifter >>= 1;
936 /* if we found a valid arg earlier, return it now */
939 return iterator->this_arg_index;
943 /* we don't know how to handle any more args, we're done */
949 * Return the channel from the frequency (in Mhz)
950 * @param frequency of the channel
951 * @return number of the channel
954 get_channel_from_frequency (int frequency)
956 if (frequency >= 2412 && frequency <= 2472)
957 return (frequency - 2407) / 5;
958 if (frequency == 2484)
960 if (frequency >= 5000 && frequency <= 6100)
961 return (frequency - 5000) / 5;
967 * function to calculate the crc, the start of the calculation
969 * @param buf buffer to calc the crc
970 * @param len len of the buffer
974 calc_crc_osdep (const unsigned char *buf, size_t len)
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
1043 unsigned long crc = 0xFFFFFFFF;
1045 for (; len > 0; len--, buf++)
1046 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1052 * Function to calculate and check crc of the wlan packet
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
1060 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1064 crc = calc_crc_osdep (buf, len);
1066 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1067 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
1074 * Get the channel used by our WLAN interface.
1076 * @param dev pointer to the dev struct of the card
1077 * @return channel number, -1 on error
1080 linux_get_channel (const struct HardwareInfos *dev)
1087 memset (&wrq, 0, sizeof (struct iwreq));
1088 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1090 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1093 frequency = wrq.u.freq.m;
1094 if (100000000 < frequency)
1095 frequency /= 100000;
1096 else if (1000000 < frequency)
1098 if (1000 < frequency)
1099 chan = get_channel_from_frequency (frequency);
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
1115 linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1116 struct Radiotap_rx *ri)
1118 unsigned char tmpbuf[buf_size];
1120 int n, got_signal, got_noise, got_channel, fcs_removed;
1122 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1124 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1127 if (EAGAIN == errno)
1129 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1133 memset (buf, 0, buf_size);
1134 memset (ri, 0, sizeof (*ri));
1136 switch (dev->arptype_in)
1138 case ARPHRD_IEEE80211_PRISM:
1140 /* skip the prism header */
1141 if (tmpbuf[7] == 0x40)
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;
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;
1161 n = *(int *) (tmpbuf + 4);
1164 if ( (n < 8) || (n >= caplen) )
1169 case ARPHRD_IEEE80211_FULL:
1171 struct ieee80211_radiotap_iterator iterator;
1172 struct ieee80211_radiotap_header *rthdr;
1174 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1176 if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
1179 /* go through the radiotap arguments we have been given
1183 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1186 switch (iterator.this_arg_index)
1189 case IEEE80211_RADIOTAP_TSFT:
1190 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1193 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1196 if (*iterator.this_arg < 127)
1197 ri->ri_power = *iterator.this_arg;
1199 ri->ri_power = *iterator.this_arg - 255;
1205 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1208 if (*iterator.this_arg < 127)
1209 ri->ri_power = *iterator.this_arg;
1211 ri->ri_power = *iterator.this_arg - 255;
1217 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1220 if (*iterator.this_arg < 127)
1221 ri->ri_noise = *iterator.this_arg;
1223 ri->ri_noise = *iterator.this_arg - 255;
1229 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1232 if (*iterator.this_arg < 127)
1233 ri->ri_noise = *iterator.this_arg;
1235 ri->ri_noise = *iterator.this_arg - 255;
1241 case IEEE80211_RADIOTAP_ANTENNA:
1242 ri->ri_antenna = *iterator.this_arg;
1245 case IEEE80211_RADIOTAP_CHANNEL:
1246 ri->ri_channel = *iterator.this_arg;
1250 case IEEE80211_RADIOTAP_RATE:
1251 ri->ri_rate = (*iterator.this_arg) * 500000;
1254 case IEEE80211_RADIOTAP_FLAGS:
1255 /* is the CRC visible at the end?
1258 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1264 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1270 n = GNUNET_le16toh (rthdr->it_len);
1271 if (n <= 0 || n >= caplen)
1275 case ARPHRD_IEEE80211:
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)))
1290 memcpy (buf, tmpbuf + n, caplen);
1292 ri->ri_channel = linux_get_channel (dev);
1299 * Open the wireless network interface for reading/writing.
1301 * @param dev pointer to the device struct
1302 * @return 0 on success
1305 open_device_raw (struct HardwareInfos *dev)
1309 struct packet_mreq mr;
1310 struct sockaddr_ll sll;
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))
1317 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1318 IFNAMSIZ, dev->iface, strerror (errno));
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))
1329 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1330 IFNAMSIZ, dev->iface, strerror (errno));
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))
1339 /* most probably not supported (ie for rtap ipw interface) *
1340 * so just assume its correctly set... */
1341 wrq.u.mode = IW_MODE_MONITOR;
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))
1349 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1350 IFNAMSIZ, dev->iface);
1354 /* Is interface st to up, broadcast & running ? */
1355 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1357 /* Bring interface up */
1358 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1360 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1362 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1363 IFNAMSIZ, dev->iface, strerror (errno));
1368 /* bind the raw socket to the interface */
1369 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1371 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1372 dev->iface, strerror (errno));
1376 /* lookup the hardware type */
1377 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1379 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1380 IFNAMSIZ, dev->iface, strerror (errno));
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))
1390 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1391 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1395 /* enable promiscuous mode */
1396 memset (&mr, 0, sizeof (mr));
1397 mr.mr_ifindex = sll.sll_ifindex;
1398 mr.mr_type = PACKET_MR_PROMISC;
1400 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1403 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1404 IFNAMSIZ, dev->iface);
1413 * Test if the given interface name really corresponds to a wireless
1416 * @param iface name of the interface
1417 * @return 0 on success, 1 on error
1420 test_wlan_interface (const char *iface)
1426 /* mac80211 stack detection */
1428 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1430 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1432 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1440 * Function to test incoming packets mac for being our own.
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
1447 mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1448 const struct HardwareInfos *dev)
1450 if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1452 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1454 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
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
1466 mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1467 const struct HardwareInfos *dev)
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);
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
1482 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1484 struct HardwareInfos *dev = cls;
1485 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
1486 struct ieee80211_frame *wlanheader;
1488 struct RadioTapheader rtheader;
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;
1496 GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1498 sendsize = ntohs (hdr->size);
1500 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1502 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
1506 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1508 if (MAXLINE < sendsize)
1510 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1513 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1515 fprintf (stderr, "Function stdin_send_hw: wrong packet type\n");
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);
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.
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
1542 main (int argc, char *argv[])
1544 struct HardwareInfos dev;
1545 char readbuf[MAXLINE];
1550 struct MessageStreamTokenizer *stdin_mst;
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 */
1559 uid_t uid = getuid ();
1560 #ifdef HAVE_SETRESUID
1561 if (0 != setresuid (uid, uid, uid))
1563 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1564 if (-1 != dev.fd_raw)
1565 (void) close (dev.fd_raw);
1569 if (0 != (setuid (uid) | seteuid (uid)))
1571 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1572 if (-1 != dev.fd_raw)
1573 (void) close (dev.fd_raw);
1579 /* now that we've dropped root rights, we can do error checking */
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);
1589 if (-1 == dev.fd_raw)
1591 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1594 if (dev.fd_raw >= FD_SETSIZE)
1596 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1597 dev.fd_raw, FD_SETSIZE);
1598 (void) close (dev.fd_raw);
1601 if (0 != test_wlan_interface (argv[1]))
1603 (void) close (dev.fd_raw);
1606 strncpy (dev.iface, argv[1], IFNAMSIZ);
1607 if (0 != open_device_raw (&dev))
1609 (void) close (dev.fd_raw);
1613 /* send MAC address of the WLAN interface to STDOUT first */
1615 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
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);
1624 stdin_mst = mst_create (&stdin_send_hw, &dev);
1630 if ((0 == write_pout.size) && (1 == stdin_open))
1632 FD_SET (STDIN_FILENO, &rfds);
1633 maxfd = MAX (maxfd, STDIN_FILENO);
1635 if (0 == write_std.size)
1637 FD_SET (dev.fd_raw, &rfds);
1638 maxfd = MAX (maxfd, dev.fd_raw);
1641 if (0 < write_std.size)
1643 FD_SET (STDOUT_FILENO, &wfds);
1644 maxfd = MAX (maxfd, STDOUT_FILENO);
1646 if (0 < write_pout.size)
1648 FD_SET (dev.fd_raw, &wfds);
1649 maxfd = MAX (maxfd, dev.fd_raw);
1652 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1653 if ((-1 == retval) && (EINTR == errno))
1657 fprintf (stderr, "select failed: %s\n", strerror (errno));
1661 if (FD_ISSET (STDOUT_FILENO, &wfds))
1664 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1665 write_std.size - write_std.pos);
1668 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1671 write_std.pos += ret;
1672 if (write_std.pos == write_std.size)
1678 if (FD_ISSET (dev.fd_raw, &wfds))
1681 write (dev.fd_raw, write_pout.buf + write_std.pos,
1682 write_pout.size - write_pout.pos);
1685 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1689 write_pout.pos += ret;
1690 if ((write_pout.pos != write_pout.size) && (0 != ret))
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);
1698 if (write_pout.pos == write_pout.size)
1701 write_pout.size = 0;
1705 if (FD_ISSET (STDIN_FILENO, &rfds))
1708 read (STDIN_FILENO, readbuf, sizeof (readbuf));
1711 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1716 /* stop reading... */
1719 mst_receive (stdin_mst, readbuf, ret);
1722 if (FD_ISSET (dev.fd_raw, &rfds))
1724 struct GNUNET_MessageHeader *header;
1725 struct Radiotap_rx *rxinfo;
1726 struct ieee80211_frame *datastart;
1729 header = (struct GNUNET_MessageHeader *) write_std.buf;
1730 rxinfo = (struct Radiotap_rx *) &header[1];
1731 datastart = (struct ieee80211_frame *) &rxinfo[1];
1733 linux_read (&dev, (unsigned char *) datastart,
1734 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1735 sizeof (struct GNUNET_MessageHeader), rxinfo);
1738 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1741 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
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);
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' */
1758 /* end of gnunet-helper-transport-wlan.c */