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)
1059 crc = calc_crc_osdep (buf, len);
1061 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1062 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
1067 * function to get the channel of a specific wlan card
1068 * @param dev pointer to the dev struct of the card
1069 * @return channel number
1072 linux_get_channel (const struct HardwareInfos *dev)
1079 memset (&wrq, 0, sizeof (struct iwreq));
1080 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1082 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1085 frequency = wrq.u.freq.m;
1086 if (100000000 < frequency)
1087 frequency /= 100000;
1088 else if (1000000 < frequency)
1090 if (1000 < frequency)
1091 chan = get_channel_from_frequency (frequency);
1099 * function to read from a wlan card
1100 * @param dev pointer to the struct of the wlan card
1101 * @param buf buffer to read to
1102 * @param buf_size size of the buffer
1103 * @param ri radiotap_rx info
1104 * @return size read from the buffer
1107 linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1108 struct Radiotap_rx *ri)
1110 unsigned char tmpbuf[buf_size];
1112 int n, got_signal, got_noise, got_channel, fcs_removed;
1114 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1116 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1119 if (EAGAIN == errno)
1121 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1125 memset (buf, 0, buf_size);
1126 memset (ri, 0, sizeof (*ri));
1128 switch (dev->arptype_in)
1130 case ARPHRD_IEEE80211_PRISM:
1132 /* skip the prism header */
1133 if (tmpbuf[7] == 0x40)
1135 /* prism54 uses a different format */
1136 ri->ri_power = tmpbuf[0x33];
1137 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
1138 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
1145 ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48);
1146 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
1147 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
1148 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
1149 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
1153 n = *(int *) (tmpbuf + 4);
1156 if ( (n < 8) || (n >= caplen) )
1161 case ARPHRD_IEEE80211_FULL:
1163 struct ieee80211_radiotap_iterator iterator;
1164 struct ieee80211_radiotap_header *rthdr;
1166 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1168 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
1171 /* go through the radiotap arguments we have been given
1175 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1178 switch (iterator.this_arg_index)
1181 case IEEE80211_RADIOTAP_TSFT:
1182 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1185 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1188 if (*iterator.this_arg < 127)
1189 ri->ri_power = *iterator.this_arg;
1191 ri->ri_power = *iterator.this_arg - 255;
1197 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1200 if (*iterator.this_arg < 127)
1201 ri->ri_power = *iterator.this_arg;
1203 ri->ri_power = *iterator.this_arg - 255;
1209 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1212 if (*iterator.this_arg < 127)
1213 ri->ri_noise = *iterator.this_arg;
1215 ri->ri_noise = *iterator.this_arg - 255;
1221 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1224 if (*iterator.this_arg < 127)
1225 ri->ri_noise = *iterator.this_arg;
1227 ri->ri_noise = *iterator.this_arg - 255;
1233 case IEEE80211_RADIOTAP_ANTENNA:
1234 ri->ri_antenna = *iterator.this_arg;
1237 case IEEE80211_RADIOTAP_CHANNEL:
1238 ri->ri_channel = *iterator.this_arg;
1242 case IEEE80211_RADIOTAP_RATE:
1243 ri->ri_rate = (*iterator.this_arg) * 500000;
1246 case IEEE80211_RADIOTAP_FLAGS:
1247 /* is the CRC visible at the end?
1250 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1256 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1262 n = GNUNET_le16toh (rthdr->it_len);
1263 if (n <= 0 || n >= caplen)
1267 case ARPHRD_IEEE80211:
1277 //detect fcs at the end, even if the flag wasn't set and remove it
1278 if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
1282 memcpy (buf, tmpbuf + n, caplen);
1284 ri->ri_channel = linux_get_channel (dev);
1291 * function to open the device for read/write
1292 * @param dev pointer to the device struct
1293 * @return 0 on success
1296 open_device_raw (struct HardwareInfos *dev)
1300 struct packet_mreq mr;
1301 struct sockaddr_ll sll;
1303 /* find the interface index */
1304 memset (&ifr, 0, sizeof (ifr));
1305 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1306 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1308 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1309 IFNAMSIZ, dev->iface, strerror (errno));
1313 /* lookup the hardware type */
1314 memset (&sll, 0, sizeof (sll));
1315 sll.sll_family = AF_PACKET;
1316 sll.sll_ifindex = ifr.ifr_ifindex;
1317 sll.sll_protocol = htons (ETH_P_ALL);
1318 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1320 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1321 IFNAMSIZ, dev->iface, strerror (errno));
1325 /* lookup iw mode */
1326 memset (&wrq, 0, sizeof (struct iwreq));
1327 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1328 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1330 /* most probably not supported (ie for rtap ipw interface) *
1331 * so just assume its correctly set... */
1332 wrq.u.mode = IW_MODE_MONITOR;
1335 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1336 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1337 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
1338 (wrq.u.mode != IW_MODE_MONITOR))
1340 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1341 IFNAMSIZ, dev->iface);
1345 /* Is interface st to up, broadcast & running ? */
1346 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1348 /* Bring interface up */
1349 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1351 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1353 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1354 IFNAMSIZ, dev->iface, strerror (errno));
1359 /* bind the raw socket to the interface */
1360 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1362 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1363 dev->iface, strerror (errno));
1367 /* lookup the hardware type */
1368 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1370 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1371 IFNAMSIZ, dev->iface, strerror (errno));
1375 memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1376 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1377 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1378 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1379 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1381 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1382 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1386 /* enable promiscuous mode */
1387 memset (&mr, 0, sizeof (mr));
1388 mr.mr_ifindex = sll.sll_ifindex;
1389 mr.mr_type = PACKET_MR_PROMISC;
1391 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1394 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1395 IFNAMSIZ, dev->iface);
1404 * function to prepare the helper, e.g. sockets, device...
1405 * @param dev struct for the device
1406 * @param iface name of the interface
1407 * @return 0 on success
1410 wlan_initialize (struct HardwareInfos *dev, const char *iface)
1416 if (dev->fd_raw >= FD_SETSIZE)
1418 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1419 dev->fd_raw, FD_SETSIZE);
1420 close (dev->fd_raw);
1424 /* mac80211 stack detection */
1426 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1428 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1430 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1431 close (dev->fd_raw);
1434 strncpy (dev->iface, iface, IFNAMSIZ);
1435 if (0 != open_device_raw (dev))
1437 close (dev->fd_raw);
1445 * Function to test incoming packets mac for being our own.
1447 * @param uint8_taIeeeHeader buffer of the packet
1448 * @param dev the Hardware_Infos struct
1449 * @return 0 if mac belongs to us, 1 if mac is for another target
1452 mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1453 const struct HardwareInfos *dev)
1455 if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1457 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1459 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
1466 * function to set the wlan header to make attacks more difficult
1467 * @param uint8_taIeeeHeader pointer to the header of the packet
1468 * @param dev pointer to the Hardware_Infos struct
1471 mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1472 const struct HardwareInfos *dev)
1474 uint8_taIeeeHeader->i_fc[0] = 0x08;
1475 uint8_taIeeeHeader->i_fc[1] = 0x00;
1476 memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE);
1477 memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE);
1482 * function to process the data from the stdin
1483 * @param cls pointer to the device struct
1484 * @param hdr pointer to the start of the packet
1487 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1489 struct HardwareInfos *dev = cls;
1490 struct SendBuffer *write_pout = &dev->write_pout;
1491 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
1492 struct ieee80211_frame *wlanheader;
1494 struct RadioTapheader rtheader;
1496 rtheader.header.it_version = 0; /* radiotap version */
1497 rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */
1498 rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap */
1499 rtheader.rate = 0x00;
1500 rtheader.pad1 = 0x00;
1502 GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1504 sendsize = ntohs (hdr->size);
1506 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1508 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
1512 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1514 if (MAXLINE < sendsize)
1516 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1519 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1521 fprintf (stderr, "Function stdin_send_hw: wrong packet type\n");
1525 rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
1526 rtheader.rate = header->rate;
1527 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
1528 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
1529 /* payload contains MAC address, but we don't trust it, so we'll
1530 * overwrite it with OUR MAC address again to prevent mischief */
1531 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
1532 mac_set (wlanheader, dev);
1533 write_pout->size = sendsize + sizeof (rtheader);
1538 * main function of the helper
1539 * @param argc number of arguments
1540 * @param argv arguments
1541 * @return 0 on success, 1 on error
1544 main (int argc, char *argv[])
1547 struct HardwareInfos dev;
1548 char readbuf[MAXLINE];
1549 struct SendBuffer write_std;
1556 struct MessageStreamTokenizer *stdin_mst;
1559 dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1560 raw_eno = errno; /* remember for later */
1562 #ifdef HAVE_SETRESUID
1563 if (0 != setresuid (uid, uid, uid))
1565 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1566 if (-1 != dev.fd_raw)
1567 (void) close (dev.fd_raw);
1571 if (0 != (setuid (uid) | seteuid (uid)))
1573 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1574 if (-1 != dev.fd_raw)
1575 (void) close (dev.fd_raw);
1580 /* now that we've dropped root rights, we can do error checking */
1584 "You must specify the name of the interface as the first and only argument to this program.\n");
1585 if (-1 != dev.fd_raw)
1586 (void) close (dev.fd_raw);
1590 if (-1 == dev.fd_raw)
1592 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1595 if (0 != wlan_initialize (&dev, argv[1]))
1597 dev.write_pout.size = 0;
1598 dev.write_pout.pos = 0;
1599 stdin_mst = mst_create (&stdin_send_hw, &dev);
1601 /* send mac to STDOUT first */
1603 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac);
1610 if ((0 == dev.write_pout.size) && (1 == stdin_open))
1612 FD_SET (STDIN_FILENO, &rfds);
1613 maxfd = MAX (maxfd, STDIN_FILENO);
1615 if (0 == write_std.size)
1617 FD_SET (dev.fd_raw, &rfds);
1618 maxfd = MAX (maxfd, dev.fd_raw);
1621 if (0 < write_std.size)
1623 FD_SET (STDOUT_FILENO, &wfds);
1624 maxfd = MAX (maxfd, STDOUT_FILENO);
1626 if (0 < dev.write_pout.size)
1628 FD_SET (dev.fd_raw, &wfds);
1629 maxfd = MAX (maxfd, dev.fd_raw);
1631 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1632 if ((-1 == retval) && (EINTR == errno))
1636 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))
1658 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
1661 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1665 dev.write_pout.pos += ret;
1666 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
1668 /* we should not get partial sends with packet-oriented devices... */
1669 fprintf (stderr, "Write error, partial send: %u/%u\n",
1670 dev.write_pout.pos, dev.write_pout.size);
1673 if (dev.write_pout.pos == dev.write_pout.size)
1675 dev.write_pout.pos = 0;
1676 dev.write_pout.size = 0;
1680 if (FD_ISSET (STDIN_FILENO, &rfds))
1682 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
1685 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1690 /* stop reading... */
1693 mst_receive (stdin_mst, readbuf, ret);
1696 if (FD_ISSET (dev.fd_raw, &rfds))
1698 struct GNUNET_MessageHeader *header;
1699 struct Radiotap_rx *rxinfo;
1700 struct ieee80211_frame *datastart;
1702 header = (struct GNUNET_MessageHeader *) write_std.buf;
1703 rxinfo = (struct Radiotap_rx *) &header[1];
1704 datastart = (struct ieee80211_frame *) &rxinfo[1];
1706 linux_read (&dev, (unsigned char *) datastart,
1707 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1708 sizeof (struct GNUNET_MessageHeader), rxinfo);
1711 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1714 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1717 ret + sizeof (struct GNUNET_MessageHeader) +
1718 sizeof (struct Radiotap_rx);
1719 header->size = htons (write_std.size);
1720 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1725 /* Error handling, try to clean up a bit at least */
1726 mst_destroy (stdin_mst);
1727 (void) close (dev.fd_raw);
1728 return 1; /* we never exit 'normally' */
1731 /* end of gnunet-helper-transport-wlan.c */