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 * we use our local copy of ieee80211_radiotap.h
25 * - since we can't support extensions we don't understand
26 * - since linux does not include it in userspace headers
28 * Portions of this code were taken from the ieee80211_radiotap.h header,
31 * Copyright (c) 2003, 2004 David Young. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. The name of David Young may not be used to endorse or promote
42 * products derived from this software without specific prior
45 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
46 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
47 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
48 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
49 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
51 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
60 * Modifications to fit into the linux IEEE 802.11 stack,
61 * Mike Kershaw (dragorn@kismetwireless.net)
65 * @file src/transport/gnunet-helper-transport-wlan.c
66 * @brief wlan layer two server; must run as root (SUID will do)
67 * This code will work under GNU/Linux only.
68 * @author David Brodski
70 * This program serves as the mediator between the wlan interface and
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
116 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
119 /* Name Data type Units
120 * ---- --------- -----
122 * IEEE80211_RADIOTAP_TSFT __le64 microseconds
124 * Value in microseconds of the MAC's 64-bit 802.11 Time
125 * Synchronization Function timer when the first bit of the
126 * MPDU arrived at the MAC. For received frames, only.
128 * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
130 * Tx/Rx frequency in MHz, followed by flags (see below).
132 * IEEE80211_RADIOTAP_FHSS __le16 see below
134 * For frequency-hopping radios, the hop set (first byte)
135 * and pattern (second byte).
137 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s
141 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
142 * one milliwatt (dBm)
144 * RF signal power at the antenna, decibel difference from
147 * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
148 * one milliwatt (dBm)
150 * RF noise power at the antenna, decibel difference from one
153 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
155 * RF signal power at the antenna, decibel difference from an
156 * arbitrary, fixed reference.
158 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
160 * RF noise power at the antenna, decibel difference from an
161 * arbitrary, fixed reference point.
163 * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
165 * Quality of Barker code lock. Unitless. Monotonically
166 * nondecreasing with "better" lock strength. Called "Signal
167 * Quality" in datasheets. (Is there a standard way to measure
170 * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
172 * Transmit power expressed as unitless distance from max
173 * power set at factory calibration. 0 is max power.
174 * Monotonically nondecreasing with lower power levels.
176 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
178 * Transmit power expressed as decibel distance from max power
179 * set at factory calibration. 0 is max power. Monotonically
180 * nondecreasing with lower power levels.
182 * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
183 * one milliwatt (dBm)
185 * Transmit power expressed as dBm (decibels from a 1 milliwatt
186 * reference). This is the absolute power level measured at
189 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
191 * Properties of transmitted and received frames. See flags
194 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
196 * Unitless indication of the Rx/Tx antenna for this packet.
197 * The first antenna is antenna 0.
199 * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
201 * Properties of received frames. See flags defined below.
203 * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
205 * Properties of transmitted frames. See flags defined below.
207 * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data
209 * Number of rts retries a transmitted frame used.
211 * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data
213 * Number of unicast retries a transmitted frame used.
218 IEEE80211_RADIOTAP_TSFT = 0,
219 IEEE80211_RADIOTAP_FLAGS = 1,
220 IEEE80211_RADIOTAP_RATE = 2,
221 IEEE80211_RADIOTAP_CHANNEL = 3,
222 IEEE80211_RADIOTAP_FHSS = 4,
223 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
224 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
225 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
226 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
227 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
228 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
229 IEEE80211_RADIOTAP_ANTENNA = 11,
230 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
231 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
232 IEEE80211_RADIOTAP_RX_FLAGS = 14,
233 IEEE80211_RADIOTAP_TX_FLAGS = 15,
234 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
235 IEEE80211_RADIOTAP_DATA_RETRIES = 17,
236 IEEE80211_RADIOTAP_EXT = 31
239 /* For IEEE80211_RADIOTAP_FLAGS */
240 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
243 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
247 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
248 * with WEP encryption
250 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
253 #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
254 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
255 * 802.11 header and payload
256 * (to 32-bit boundary)
258 /* For IEEE80211_RADIOTAP_RX_FLAGS */
259 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
261 /* For IEEE80211_RADIOTAP_TX_FLAGS */
262 #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
264 #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
265 #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
266 #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */
267 #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled
272 * A generic radio capture format is desirable. There is one for
273 * Linux, but it is neither rigidly defined (there were not even
274 * units given for some fields) nor easily extensible.
276 * I suggest the following extensible radio capture format. It is
277 * based on a bitmap indicating which fields are present.
279 * I am trying to describe precisely what the application programmer
280 * should expect in the following, and for that reason I tell the
281 * units and origin of each measurement (where it applies), or else I
282 * use sufficiently weaselly language ("is a monotonically nondecreasing
283 * function of...") that I cannot set false expectations for lawyerly
286 * The radio capture header precedes the 802.11 header.
287 * All data in the header is little endian on all platforms.
289 struct ieee80211_radiotap_header
292 * Version 0. Only increases for drastic changes, introduction of
293 * compatible new fields does not count.
299 * length of the whole header in bytes, including it_version,
300 * it_pad, it_len, and data fields.
305 * A bitmap telling which fields are present. Set bit 31
306 * (0x80000000) to extend the bitmap by another 32 bits. Additional
307 * extensions are made by setting bit 31.
312 struct RadioTapheader
314 struct ieee80211_radiotap_header header;
328 char buf[MAXLINE * 2];
331 GNUNET_NETWORK_STRUCT_BEGIN
334 * generic definitions for IEEE 802.11 frames
336 struct ieee80211_frame
340 uint8_t i_addr1[IEEE80211_ADDR_LEN];
341 uint8_t i_addr2[IEEE80211_ADDR_LEN];
342 uint8_t i_addr3[IEEE80211_ADDR_LEN];
344 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
347 GNUNET_NETWORK_STRUCT_END
350 * struct for storing the information of the hardware
358 struct SendBuffer write_pout;
361 * file descriptor for the raw socket
368 * Name of the interface, not necessarily 0-terminated (!).
370 char iface[IFNAMSIZ];
372 struct MacAddress pl_mac;
379 #define ___my_swab16(x) \
381 (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \
382 (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) ))
384 #define ___my_swab32(x) \
386 (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \
387 (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \
388 (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \
389 (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) ))
390 #define ___my_swab64(x) \
392 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \
393 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \
394 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \
395 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) << 8) | \
396 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >> 8) | \
397 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \
398 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \
399 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) ))
404 * struct ieee80211_radiotap_iterator - tracks walk through present radiotap args
406 struct ieee80211_radiotap_iterator
409 * pointer to the radiotap header we are walking through
411 const struct ieee80211_radiotap_header *rtheader;
414 * length of radiotap header in cpu byte ordering
419 * IEEE80211_RADIOTAP_... index of current arg
421 unsigned int this_arg_index;
424 * pointer to current radiotap arg
429 * internal next argument index
431 unsigned int arg_index;
434 * internal next argument pointer
439 * internal pointer to next present uint32_t
441 uint32_t *next_bitmap;
444 * internal shifter for curr uint32_t bitmap, b0 set == arg present
446 uint32_t bitmap_shifter;
451 /* specialized version of server_mst.c begins here */
453 #define ALIGN_FACTOR 8
456 * Smallest supported message.
458 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
462 * Functions with this signature are called whenever a
463 * complete message is received by the tokenizer.
466 * @param message the actual message
468 typedef void (*MessageTokenizerCallback) (void *cls,
470 GNUNET_MessageHeader *
474 * Handle to a message stream tokenizer.
476 struct MessageStreamTokenizer
480 * Function to call on completed messages.
482 MessageTokenizerCallback cb;
490 * Size of the buffer (starting at 'hdr').
495 * How many bytes in buffer have we already processed?
500 * How many bytes in buffer are valid right now?
505 * Beginning of the buffer. Typed like this to force alignment.
507 struct GNUNET_MessageHeader *hdr;
514 * Create a message stream tokenizer.
516 * @param cb function to call on completed messages
517 * @param cb_cls closure for cb
518 * @return handle to tokenizer
520 static struct MessageStreamTokenizer *
521 mst_create (MessageTokenizerCallback cb,
524 struct MessageStreamTokenizer *ret;
526 ret = malloc (sizeof (struct MessageStreamTokenizer));
529 ret->hdr = malloc (MIN_BUFFER_SIZE);
530 if (NULL == ret->hdr)
532 ret->curr_buf = MIN_BUFFER_SIZE;
534 ret->cb_cls = cb_cls;
540 * Add incoming data to the receive buffer and call the
541 * callback for all complete messages.
543 * @param mst tokenizer to use
544 * @param buf input data to add
545 * @param size number of bytes in buf
546 * @return GNUNET_OK if we are done processing (need more data)
547 * GNUNET_SYSERR if the data stream is corrupt
550 mst_receive (struct MessageStreamTokenizer *mst,
551 const char *buf, size_t size)
553 const struct GNUNET_MessageHeader *hdr;
558 unsigned long offset;
562 ibuf = (char *) mst->hdr;
566 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
567 (0 != (mst->off % ALIGN_FACTOR)))
569 /* need to align or need more space */
570 mst->pos -= mst->off;
571 memmove (ibuf, &ibuf[mst->off], mst->pos);
574 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
577 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
578 (mst->pos - mst->off), size);
579 memcpy (&ibuf[mst->pos], buf, delta);
584 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
588 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
589 want = ntohs (hdr->size);
590 if (want < sizeof (struct GNUNET_MessageHeader))
592 // GNUNET_break_op (0);
593 return GNUNET_SYSERR;
595 if (mst->curr_buf - mst->off < want)
597 /* need more space */
598 mst->pos -= mst->off;
599 memmove (ibuf, &ibuf[mst->off], mst->pos);
602 if (want > mst->curr_buf)
604 mst->hdr = realloc (mst->hdr, want);
605 if (NULL == mst->hdr)
607 ibuf = (char *) mst->hdr;
608 mst->curr_buf = want;
610 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
611 if (mst->pos - mst->off < want)
613 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
614 memcpy (&ibuf[mst->pos], buf, delta);
619 if (mst->pos - mst->off < want)
623 mst->cb (mst->cb_cls, hdr);
625 if (mst->off == mst->pos)
627 /* reset to beginning of buffer, it's free right now! */
634 if (size < sizeof (struct GNUNET_MessageHeader))
636 offset = (unsigned long) buf;
637 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
638 if (GNUNET_NO == need_align)
640 /* can try to do zero-copy and process directly from original buffer */
641 hdr = (const struct GNUNET_MessageHeader *) buf;
642 want = ntohs (hdr->size);
643 if (want < sizeof (struct GNUNET_MessageHeader))
645 // GNUNET_break_op (0);
647 return GNUNET_SYSERR;
650 break; /* or not, buffer incomplete, so copy to private buffer... */
651 mst->cb (mst->cb_cls, hdr);
657 /* need to copy to private buffer to align;
658 * yes, we go a bit more spagetti than usual here */
664 if (size + mst->pos > mst->curr_buf)
666 mst->hdr = realloc (mst->hdr, size + mst->pos);
667 if (NULL == mst->hdr)
669 ibuf = (char *) mst->hdr;
670 mst->curr_buf = size + mst->pos;
672 // GNUNET_assert (mst->pos + size <= mst->curr_buf);
673 memcpy (&ibuf[mst->pos], buf, size);
681 * Destroys a tokenizer.
683 * @param mst tokenizer to destroy
686 mst_destroy (struct MessageStreamTokenizer *mst)
692 /* end of server_mst.c copy */
698 * Radiotap header iteration
700 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
701 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
702 * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
703 * if there are no more args in the header, or the next argument type index
704 * that is present. The iterator's this_arg member points to the start of the
705 * argument associated with the current argument index that is present,
706 * which can be found in the iterator's this_arg_index member. This arg
707 * index corresponds to the IEEE80211_RADIOTAP_... defines.
709 * @param iterator iterator to initialize
710 * @param radiotap_header message to parse
711 * @param max_length number of valid bytes in radiotap_header
712 * @return 0 on success
715 ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
716 const struct ieee80211_radiotap_header
720 if ( (iterator == NULL) ||
721 (radiotap_header == NULL) )
724 /* Linux only supports version 0 radiotap format */
725 if (0 != radiotap_header->it_version)
728 /* sanity check for allowed length and radiotap length field */
729 if ( (max_length < sizeof (struct ieee80211_radiotap_header)) ||
730 (max_length < (GNUNET_le16toh (radiotap_header->it_len))) )
733 iterator->rtheader = radiotap_header;
734 iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
735 iterator->arg_index = 0;
736 iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
738 ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
739 iterator->this_arg = 0;
741 /* find payload start allowing for extended bitmap(s) */
742 if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
744 while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
745 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
747 iterator->arg += sizeof (uint32_t);
750 * check for insanity where the present bitmaps
751 * keep claiming to extend up to or even beyond the
752 * stated radiotap header length
754 if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
757 iterator->arg += sizeof (uint32_t);
759 * no need to check again for blowing past stated radiotap
760 * header length, becuase ieee80211_radiotap_iterator_next
761 * checks it before it is dereferenced
764 /* we are all initialized happily */
770 * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
772 * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
773 * and sets iterator->this_arg to point to the payload for the arg. It takes
774 * care of alignment handling and extended present fields. interator->this_arg
775 * can be changed by the caller. The args pointed to are in little-endian
778 * @param iterator: radiotap_iterator to move to next arg (if any)
780 * @return next present arg index on success or negative if no more or error
783 ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
787 * small length lookup table for all radiotap types we heard of
788 * starting from b0 in the bitmap, so we can walk the payload
789 * area of the radiotap header
791 * There is a requirement to pad args, so that args
792 * of a given length must begin at a boundary of that length
793 * -- but note that compound args are allowed (eg, 2 x uint16_t
794 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
795 * a reliable indicator of alignment requirement.
797 * upper nybble: content alignment for arg
798 * lower nybble: content length for arg
801 static const uint8_t rt_sizes[] = {
802 [IEEE80211_RADIOTAP_TSFT] = 0x88,
803 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
804 [IEEE80211_RADIOTAP_RATE] = 0x11,
805 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
806 [IEEE80211_RADIOTAP_FHSS] = 0x22,
807 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
808 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
809 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
810 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
811 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
812 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
813 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
814 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
815 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
816 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
817 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
818 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
819 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
821 * add more here as they are defined in
822 * include/net/ieee80211_radiotap.h
827 * for every radiotap entry we can at
828 * least skip (by knowing the length)...
831 while (iterator->arg_index < sizeof (rt_sizes))
835 if (!(iterator->bitmap_shifter & 1))
836 goto next_entry; /* arg not present */
839 * arg is present, account for alignment padding
840 * 8-bit args can be at any alignment
841 * 16-bit args must start on 16-bit boundary
842 * 32-bit args must start on 32-bit boundary
843 * 64-bit args must start on 64-bit boundary
845 * note that total arg size can differ from alignment of
846 * elements inside arg, so we use upper nybble of length
847 * table to base alignment on
849 * also note: these alignments are ** relative to the
850 * start of the radiotap header **. There is no guarantee
851 * that the radiotap header itself is aligned on any
855 if ((((void *) iterator->arg) -
856 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
858 iterator->arg_index +=
859 (rt_sizes[iterator->arg_index] >> 4) -
860 ((((void *) iterator->arg) -
861 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
865 * this is what we will return to user, but we need to
866 * move on first so next call has something fresh to test
869 iterator->this_arg_index = iterator->arg_index;
870 iterator->this_arg = iterator->arg;
873 /* internally move on the size of this arg */
875 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
878 * check for insanity where we are given a bitmap that
879 * claims to have more arg content than the length of the
880 * radiotap section. We will normally end up equalling this
881 * max_length on the last arg, never exceeding it.
884 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
885 iterator->max_length)
890 iterator->arg_index++;
891 if (((iterator->arg_index & 31) == 0))
893 /* completed current uint32_t bitmap */
894 if (iterator->bitmap_shifter & 1)
896 /* b31 was set, there is more */
897 /* move to next uint32_t bitmap */
898 iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
899 iterator->next_bitmap++;
903 /* no more bitmaps: end */
904 iterator->arg_index = sizeof (rt_sizes);
908 { /* just try the next bit */
909 iterator->bitmap_shifter >>= 1;
912 /* if we found a valid arg earlier, return it now */
915 return iterator->this_arg_index;
919 /* we don't know how to handle any more args, we're done */
925 * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
926 * @param buffer pointer to buffer for the message
927 * @param mac pointer to the mac address
928 * @return number of bytes written
931 send_mac_to_plugin (char *buffer, struct MacAddress *mac)
933 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
935 memcpy (&macmsg.mac, (char *) mac, sizeof (struct MacAddress));
936 macmsg.hdr.size = htons (sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
937 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
938 memcpy (buffer, &macmsg, sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
939 return sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage);
944 * Return the channel from the frequency (in Mhz)
945 * @param frequency of the channel
946 * @return number of the channel
949 get_channel_from_frequency (int frequency)
951 if (frequency >= 2412 && frequency <= 2472)
952 return (frequency - 2407) / 5;
953 if (frequency == 2484)
955 if (frequency >= 5000 && frequency <= 6100)
956 return (frequency - 5000) / 5;
962 * function to calculate the crc, the start of the calculation
963 * @param buf buffer to calc the crc
964 * @param len len of the buffer
968 calc_crc_osdep (const unsigned char *buf, size_t len)
970 static const unsigned long int crc_tbl_osdep[256] = {
971 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
972 0xE963A535, 0x9E6495A3,
973 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
974 0xE7B82D07, 0x90BF1D91,
975 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
976 0xF4D4B551, 0x83D385C7,
977 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
978 0xFA0F3D63, 0x8D080DF5,
979 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
980 0xD20D85FD, 0xA50AB56B,
981 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
982 0xDCD60DCF, 0xABD13D59,
983 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
984 0xCFBA9599, 0xB8BDA50F,
985 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
986 0xC1611DAB, 0xB6662D3D,
987 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
988 0x9FBFE4A5, 0xE8B8D433,
989 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
990 0x91646C97, 0xE6635C01,
991 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
992 0x8208F4C1, 0xF50FC457,
993 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
994 0x8CD37CF3, 0xFBD44C65,
995 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
996 0xA4D1C46D, 0xD3D6F4FB,
997 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
998 0xAA0A4C5F, 0xDD0D7CC9,
999 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
1000 0xB966D409, 0xCE61E49F,
1001 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1002 0xB7BD5C3B, 0xC0BA6CAD,
1003 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1004 0x04DB2615, 0x73DC1683,
1005 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1006 0x0A00AE27, 0x7D079EB1,
1007 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1008 0x196C3671, 0x6E6B06E7,
1009 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1010 0x17B7BE43, 0x60B08ED5,
1011 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1012 0x3FB506DD, 0x48B2364B,
1013 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1014 0x316E8EEF, 0x4669BE79,
1015 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1016 0x220216B9, 0x5505262F,
1017 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1018 0x2CD99E8B, 0x5BDEAE1D,
1019 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1020 0x72076785, 0x05005713,
1021 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1022 0x7CDCEFB7, 0x0BDBDF21,
1023 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1024 0x6FB077E1, 0x18B74777,
1025 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1026 0x616BFFD3, 0x166CCF45,
1027 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1028 0x4969474D, 0x3E6E77DB,
1029 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1030 0x47B2CF7F, 0x30B5FFE9,
1031 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1032 0x54DE5729, 0x23D967BF,
1033 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1034 0x5A05DF1B, 0x2D02EF8D
1037 unsigned long crc = 0xFFFFFFFF;
1039 for (; len > 0; len--, buf++)
1040 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1046 * Function to check crc of the wlan packet
1047 * @param buf buffer of the packet
1048 * @param len len of the data
1049 * @return crc sum of the data
1052 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1056 crc = calc_crc_osdep (buf, len);
1058 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1059 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
1064 * function to get the channel of a specific wlan card
1065 * @param dev pointer to the dev struct of the card
1066 * @return channel number
1069 linux_get_channel (const struct HardwareInfos *dev)
1076 memset (&wrq, 0, sizeof (struct iwreq));
1077 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1079 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1082 frequency = wrq.u.freq.m;
1083 if (100000000 < frequency)
1084 frequency /= 100000;
1085 else if (1000000 < frequency)
1087 if (1000 < frequency)
1088 chan = get_channel_from_frequency (frequency);
1096 * function to read from a wlan card
1097 * @param dev pointer to the struct of the wlan card
1098 * @param buf buffer to read to
1099 * @param buf_size size of the buffer
1100 * @param ri radiotap_rx info
1101 * @return size read from the buffer
1104 linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1105 struct Radiotap_rx *ri)
1107 unsigned char tmpbuf[buf_size];
1109 int n, got_signal, got_noise, got_channel, fcs_removed;
1111 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1113 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1116 if (EAGAIN == errno)
1118 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1122 memset (buf, 0, buf_size);
1123 memset (ri, 0, sizeof (*ri));
1125 switch (dev->arptype_in)
1127 case ARPHRD_IEEE80211_PRISM:
1129 /* skip the prism header */
1130 if (tmpbuf[7] == 0x40)
1132 /* prism54 uses a different format */
1133 ri->ri_power = tmpbuf[0x33];
1134 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
1135 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
1142 ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48);
1143 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
1144 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
1145 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
1146 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
1150 n = *(int *) (tmpbuf + 4);
1153 if ( (n < 8) || (n >= caplen) )
1158 case ARPHRD_IEEE80211_FULL:
1160 struct ieee80211_radiotap_iterator iterator;
1161 struct ieee80211_radiotap_header *rthdr;
1163 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1165 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
1168 /* go through the radiotap arguments we have been given
1172 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1175 switch (iterator.this_arg_index)
1178 case IEEE80211_RADIOTAP_TSFT:
1179 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1182 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1185 if (*iterator.this_arg < 127)
1186 ri->ri_power = *iterator.this_arg;
1188 ri->ri_power = *iterator.this_arg - 255;
1194 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1197 if (*iterator.this_arg < 127)
1198 ri->ri_power = *iterator.this_arg;
1200 ri->ri_power = *iterator.this_arg - 255;
1206 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1209 if (*iterator.this_arg < 127)
1210 ri->ri_noise = *iterator.this_arg;
1212 ri->ri_noise = *iterator.this_arg - 255;
1218 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1221 if (*iterator.this_arg < 127)
1222 ri->ri_noise = *iterator.this_arg;
1224 ri->ri_noise = *iterator.this_arg - 255;
1230 case IEEE80211_RADIOTAP_ANTENNA:
1231 ri->ri_antenna = *iterator.this_arg;
1234 case IEEE80211_RADIOTAP_CHANNEL:
1235 ri->ri_channel = *iterator.this_arg;
1239 case IEEE80211_RADIOTAP_RATE:
1240 ri->ri_rate = (*iterator.this_arg) * 500000;
1243 case IEEE80211_RADIOTAP_FLAGS:
1244 /* is the CRC visible at the end?
1247 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1253 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1259 n = GNUNET_le16toh (rthdr->it_len);
1260 if (n <= 0 || n >= caplen)
1264 case ARPHRD_IEEE80211:
1274 //detect fcs at the end, even if the flag wasn't set and remove it
1275 if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
1279 memcpy (buf, tmpbuf + n, caplen);
1281 ri->ri_channel = linux_get_channel (dev);
1288 * function to open the device for read/write
1289 * @param dev pointer to the device struct
1290 * @return 0 on success
1293 open_device_raw (struct HardwareInfos *dev)
1297 struct packet_mreq mr;
1298 struct sockaddr_ll sll;
1300 /* find the interface index */
1301 memset (&ifr, 0, sizeof (ifr));
1302 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1303 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1305 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1306 IFNAMSIZ, dev->iface, strerror (errno));
1310 /* lookup the hardware type */
1311 memset (&sll, 0, sizeof (sll));
1312 sll.sll_family = AF_PACKET;
1313 sll.sll_ifindex = ifr.ifr_ifindex;
1314 sll.sll_protocol = htons (ETH_P_ALL);
1315 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1317 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1318 IFNAMSIZ, dev->iface, strerror (errno));
1322 /* lookup iw mode */
1323 memset (&wrq, 0, sizeof (struct iwreq));
1324 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1325 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1327 /* most probably not supported (ie for rtap ipw interface) *
1328 * so just assume its correctly set... */
1329 wrq.u.mode = IW_MODE_MONITOR;
1332 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1333 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1334 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
1335 (wrq.u.mode != IW_MODE_MONITOR))
1337 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1338 IFNAMSIZ, dev->iface);
1342 /* Is interface st to up, broadcast & running ? */
1343 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1345 /* Bring interface up */
1346 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1348 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1350 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1351 IFNAMSIZ, dev->iface, strerror (errno));
1356 /* bind the raw socket to the interface */
1357 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1359 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1360 dev->iface, strerror (errno));
1364 /* lookup the hardware type */
1365 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1367 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1368 IFNAMSIZ, dev->iface, strerror (errno));
1372 memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1373 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1374 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1375 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1376 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1378 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1379 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1383 /* enable promiscuous mode */
1384 memset (&mr, 0, sizeof (mr));
1385 mr.mr_ifindex = sll.sll_ifindex;
1386 mr.mr_type = PACKET_MR_PROMISC;
1388 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1391 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1392 IFNAMSIZ, dev->iface);
1401 * function to prepare the helper, e.g. sockets, device...
1402 * @param dev struct for the device
1403 * @param iface name of the interface
1404 * @return 0 on success
1407 wlan_initialize (struct HardwareInfos *dev, const char *iface)
1413 if (dev->fd_raw >= FD_SETSIZE)
1415 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1416 dev->fd_raw, FD_SETSIZE);
1417 close (dev->fd_raw);
1421 /* mac80211 stack detection */
1423 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1425 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1427 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1428 close (dev->fd_raw);
1431 strncpy (dev->iface, iface, IFNAMSIZ);
1432 if (0 != open_device_raw (dev))
1434 close (dev->fd_raw);
1442 * Function to test incoming packets mac for being our own.
1444 * @param uint8_taIeeeHeader buffer of the packet
1445 * @param dev the Hardware_Infos struct
1446 * @return 0 if mac belongs to us, 1 if mac is for another target
1449 mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1450 const struct HardwareInfos *dev)
1452 if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1454 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1456 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
1463 * function to set the wlan header to make attacks more difficult
1464 * @param uint8_taIeeeHeader pointer to the header of the packet
1465 * @param dev pointer to the Hardware_Infos struct
1468 mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1469 const struct HardwareInfos *dev)
1471 uint8_taIeeeHeader->i_fc[0] = 0x08;
1472 uint8_taIeeeHeader->i_fc[1] = 0x00;
1473 memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE);
1474 memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE);
1479 * function to process the data from the stdin
1480 * @param cls pointer to the device struct
1481 * @param hdr pointer to the start of the packet
1484 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1486 struct HardwareInfos *dev = cls;
1487 struct SendBuffer *write_pout = &dev->write_pout;
1488 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
1489 struct ieee80211_frame *wlanheader;
1491 struct RadioTapheader rtheader;
1493 rtheader.header.it_version = 0; /* radiotap version */
1494 rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */
1495 rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap */
1496 rtheader.rate = 0x00;
1497 rtheader.pad1 = 0x00;
1499 GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1501 sendsize = ntohs (hdr->size);
1503 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1505 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
1509 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1511 if (MAXLINE < sendsize)
1513 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1516 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1518 fprintf (stderr, "Function stdin_send_hw: wrong packet type\n");
1522 rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
1523 rtheader.rate = header->rate;
1524 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
1525 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
1526 /* payload contains MAC address, but we don't trust it, so we'll
1527 * overwrite it with OUR MAC address again to prevent mischief */
1528 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
1529 mac_set (wlanheader, dev);
1530 write_pout->size = sendsize + sizeof (rtheader);
1535 * main function of the helper
1536 * @param argc number of arguments
1537 * @param argv arguments
1538 * @return 0 on success, 1 on error
1541 main (int argc, char *argv[])
1544 struct HardwareInfos dev;
1545 char readbuf[MAXLINE];
1546 struct SendBuffer write_std;
1553 struct MessageStreamTokenizer *stdin_mst;
1556 dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1557 raw_eno = errno; /* remember for later */
1559 #ifdef HAVE_SETRESUID
1560 if (0 != setresuid (uid, uid, uid))
1562 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1563 if (-1 != dev.fd_raw)
1564 (void) close (dev.fd_raw);
1568 if (0 != (setuid (uid) | seteuid (uid)))
1570 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1571 if (-1 != dev.fd_raw)
1572 (void) close (dev.fd_raw);
1577 /* now that we've dropped root rights, we can do error checking */
1581 "You must specify the name of the interface as the first and only argument to this program.\n");
1582 if (-1 != dev.fd_raw)
1583 (void) close (dev.fd_raw);
1587 if (-1 == dev.fd_raw)
1589 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1592 if (0 != wlan_initialize (&dev, argv[1]))
1594 dev.write_pout.size = 0;
1595 dev.write_pout.pos = 0;
1596 stdin_mst = mst_create (&stdin_send_hw, &dev);
1598 /* send mac to STDOUT first */
1600 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac);
1607 if ((0 == dev.write_pout.size) && (1 == stdin_open))
1609 FD_SET (STDIN_FILENO, &rfds);
1610 maxfd = MAX (maxfd, STDIN_FILENO);
1612 if (0 == write_std.size)
1614 FD_SET (dev.fd_raw, &rfds);
1615 maxfd = MAX (maxfd, dev.fd_raw);
1618 if (0 < write_std.size)
1620 FD_SET (STDOUT_FILENO, &wfds);
1621 maxfd = MAX (maxfd, STDOUT_FILENO);
1623 if (0 < dev.write_pout.size)
1625 FD_SET (dev.fd_raw, &wfds);
1626 maxfd = MAX (maxfd, dev.fd_raw);
1628 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1629 if ((-1 == retval) && (EINTR == errno))
1633 fprintf (stderr, "select failed: %s\n", strerror (errno));
1636 if (FD_ISSET (STDOUT_FILENO, &wfds))
1639 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1640 write_std.size - write_std.pos);
1643 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1646 write_std.pos += ret;
1647 if (write_std.pos == write_std.size)
1653 if (FD_ISSET (dev.fd_raw, &wfds))
1655 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
1658 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1662 dev.write_pout.pos += ret;
1663 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
1665 /* we should not get partial sends with packet-oriented devices... */
1666 fprintf (stderr, "Write error, partial send: %u/%u\n",
1667 dev.write_pout.pos, dev.write_pout.size);
1670 if (dev.write_pout.pos == dev.write_pout.size)
1672 dev.write_pout.pos = 0;
1673 dev.write_pout.size = 0;
1677 if (FD_ISSET (STDIN_FILENO, &rfds))
1679 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
1682 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1687 /* stop reading... */
1690 mst_receive (stdin_mst, readbuf, ret);
1693 if (FD_ISSET (dev.fd_raw, &rfds))
1695 struct GNUNET_MessageHeader *header;
1696 struct Radiotap_rx *rxinfo;
1697 struct ieee80211_frame *datastart;
1699 header = (struct GNUNET_MessageHeader *) write_std.buf;
1700 rxinfo = (struct Radiotap_rx *) &header[1];
1701 datastart = (struct ieee80211_frame *) &rxinfo[1];
1703 linux_read (&dev, (unsigned char *) datastart,
1704 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1705 sizeof (struct GNUNET_MessageHeader), rxinfo);
1708 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1711 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1714 ret + sizeof (struct GNUNET_MessageHeader) +
1715 sizeof (struct Radiotap_rx);
1716 header->size = htons (write_std.size);
1717 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1722 /* Error handling, try to clean up a bit at least */
1723 mst_destroy (stdin_mst);
1724 (void) close (dev.fd_raw);
1725 return 1; /* we never exit 'normally' */
1728 /* end of gnunet-helper-transport-wlan.c */