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];
333 * generic definitions for IEEE 802.11 frames
335 struct ieee80211_frame
339 uint8_t i_addr1[IEEE80211_ADDR_LEN];
340 uint8_t i_addr2[IEEE80211_ADDR_LEN];
341 uint8_t i_addr3[IEEE80211_ADDR_LEN];
343 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
349 * struct for storing the information of the hardware
357 struct SendBuffer write_pout;
360 * file descriptor for the raw socket
367 * Name of the interface, not necessarily 0-terminated (!).
369 char iface[IFNAMSIZ];
371 struct MacAddress pl_mac;
378 #define ___my_swab16(x) \
380 (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \
381 (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) ))
383 #define ___my_swab32(x) \
385 (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \
386 (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \
387 (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \
388 (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) ))
389 #define ___my_swab64(x) \
391 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \
392 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \
393 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \
394 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) << 8) | \
395 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >> 8) | \
396 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \
397 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \
398 (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) ))
403 * struct ieee80211_radiotap_iterator - tracks walk through present radiotap args
405 struct ieee80211_radiotap_iterator
408 * pointer to the radiotap header we are walking through
410 const struct ieee80211_radiotap_header *rtheader;
413 * length of radiotap header in cpu byte ordering
418 * IEEE80211_RADIOTAP_... index of current arg
420 unsigned int this_arg_index;
423 * pointer to current radiotap arg
428 * internal next argument index
430 unsigned int arg_index;
433 * internal next argument pointer
438 * internal pointer to next present uint32_t
440 uint32_t *next_bitmap;
443 * internal shifter for curr uint32_t bitmap, b0 set == arg present
445 uint32_t bitmap_shifter;
450 /* specialized version of server_mst.c begins here */
452 #define ALIGN_FACTOR 8
455 * Smallest supported message.
457 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
461 * Functions with this signature are called whenever a
462 * complete message is received by the tokenizer.
465 * @param message the actual message
467 typedef void (*MessageTokenizerCallback) (void *cls,
469 GNUNET_MessageHeader *
473 * Handle to a message stream tokenizer.
475 struct MessageStreamTokenizer
479 * Function to call on completed messages.
481 MessageTokenizerCallback cb;
489 * Size of the buffer (starting at 'hdr').
494 * How many bytes in buffer have we already processed?
499 * How many bytes in buffer are valid right now?
504 * Beginning of the buffer. Typed like this to force alignment.
506 struct GNUNET_MessageHeader *hdr;
513 * Create a message stream tokenizer.
515 * @param cb function to call on completed messages
516 * @param cb_cls closure for cb
517 * @return handle to tokenizer
519 static struct MessageStreamTokenizer *
520 mst_create (MessageTokenizerCallback cb,
523 struct MessageStreamTokenizer *ret;
525 ret = malloc (sizeof (struct MessageStreamTokenizer));
528 ret->hdr = malloc (MIN_BUFFER_SIZE);
529 if (NULL == ret->hdr)
531 ret->curr_buf = MIN_BUFFER_SIZE;
533 ret->cb_cls = cb_cls;
539 * Add incoming data to the receive buffer and call the
540 * callback for all complete messages.
542 * @param mst tokenizer to use
543 * @param buf input data to add
544 * @param size number of bytes in buf
545 * @return GNUNET_OK if we are done processing (need more data)
546 * GNUNET_SYSERR if the data stream is corrupt
549 mst_receive (struct MessageStreamTokenizer *mst,
550 const char *buf, size_t size)
552 const struct GNUNET_MessageHeader *hdr;
557 unsigned long offset;
561 ibuf = (char *) mst->hdr;
565 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
566 (0 != (mst->off % ALIGN_FACTOR)))
568 /* need to align or need more space */
569 mst->pos -= mst->off;
570 memmove (ibuf, &ibuf[mst->off], mst->pos);
573 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
576 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
577 (mst->pos - mst->off), size);
578 memcpy (&ibuf[mst->pos], buf, delta);
583 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
587 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
588 want = ntohs (hdr->size);
589 if (want < sizeof (struct GNUNET_MessageHeader))
591 // GNUNET_break_op (0);
592 return GNUNET_SYSERR;
594 if (mst->curr_buf - mst->off < want)
596 /* need more space */
597 mst->pos -= mst->off;
598 memmove (ibuf, &ibuf[mst->off], mst->pos);
601 if (want > mst->curr_buf)
603 mst->hdr = realloc (mst->hdr, want);
604 if (NULL == mst->hdr)
606 ibuf = (char *) mst->hdr;
607 mst->curr_buf = want;
609 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
610 if (mst->pos - mst->off < want)
612 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
613 memcpy (&ibuf[mst->pos], buf, delta);
618 if (mst->pos - mst->off < want)
622 mst->cb (mst->cb_cls, hdr);
624 if (mst->off == mst->pos)
626 /* reset to beginning of buffer, it's free right now! */
633 if (size < sizeof (struct GNUNET_MessageHeader))
635 offset = (unsigned long) buf;
636 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
637 if (GNUNET_NO == need_align)
639 /* can try to do zero-copy and process directly from original buffer */
640 hdr = (const struct GNUNET_MessageHeader *) buf;
641 want = ntohs (hdr->size);
642 if (want < sizeof (struct GNUNET_MessageHeader))
644 // GNUNET_break_op (0);
646 return GNUNET_SYSERR;
649 break; /* or not, buffer incomplete, so copy to private buffer... */
650 mst->cb (mst->cb_cls, hdr);
656 /* need to copy to private buffer to align;
657 * yes, we go a bit more spagetti than usual here */
663 if (size + mst->pos > mst->curr_buf)
665 mst->hdr = realloc (mst->hdr, size + mst->pos);
666 if (NULL == mst->hdr)
668 ibuf = (char *) mst->hdr;
669 mst->curr_buf = size + mst->pos;
671 // GNUNET_assert (mst->pos + size <= mst->curr_buf);
672 memcpy (&ibuf[mst->pos], buf, size);
680 * Destroys a tokenizer.
682 * @param mst tokenizer to destroy
685 mst_destroy (struct MessageStreamTokenizer *mst)
691 /* end of server_mst.c copy */
697 * Radiotap header iteration
699 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
700 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
701 * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
702 * if there are no more args in the header, or the next argument type index
703 * that is present. The iterator's this_arg member points to the start of the
704 * argument associated with the current argument index that is present,
705 * which can be found in the iterator's this_arg_index member. This arg
706 * index corresponds to the IEEE80211_RADIOTAP_... defines.
708 * @param iterator iterator to initialize
709 * @param radiotap_header message to parse
710 * @param max_length number of valid bytes in radiotap_header
711 * @return 0 on success
714 ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
715 const struct ieee80211_radiotap_header
719 if ( (iterator == NULL) ||
720 (radiotap_header == NULL) )
723 /* Linux only supports version 0 radiotap format */
724 if (0 != radiotap_header->it_version)
727 /* sanity check for allowed length and radiotap length field */
728 if ( (max_length < sizeof (struct ieee80211_radiotap_header)) ||
729 (max_length < (GNUNET_le16toh (radiotap_header->it_len))) )
732 iterator->rtheader = radiotap_header;
733 iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
734 iterator->arg_index = 0;
735 iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
737 ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
738 iterator->this_arg = 0;
740 /* find payload start allowing for extended bitmap(s) */
741 if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
743 while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
744 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
746 iterator->arg += sizeof (uint32_t);
749 * check for insanity where the present bitmaps
750 * keep claiming to extend up to or even beyond the
751 * stated radiotap header length
753 if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
756 iterator->arg += sizeof (uint32_t);
758 * no need to check again for blowing past stated radiotap
759 * header length, becuase ieee80211_radiotap_iterator_next
760 * checks it before it is dereferenced
763 /* we are all initialized happily */
769 * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
771 * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
772 * and sets iterator->this_arg to point to the payload for the arg. It takes
773 * care of alignment handling and extended present fields. interator->this_arg
774 * can be changed by the caller. The args pointed to are in little-endian
777 * @param iterator: radiotap_iterator to move to next arg (if any)
779 * @return next present arg index on success or negative if no more or error
782 ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
786 * small length lookup table for all radiotap types we heard of
787 * starting from b0 in the bitmap, so we can walk the payload
788 * area of the radiotap header
790 * There is a requirement to pad args, so that args
791 * of a given length must begin at a boundary of that length
792 * -- but note that compound args are allowed (eg, 2 x uint16_t
793 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
794 * a reliable indicator of alignment requirement.
796 * upper nybble: content alignment for arg
797 * lower nybble: content length for arg
800 static const uint8_t rt_sizes[] = {
801 [IEEE80211_RADIOTAP_TSFT] = 0x88,
802 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
803 [IEEE80211_RADIOTAP_RATE] = 0x11,
804 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
805 [IEEE80211_RADIOTAP_FHSS] = 0x22,
806 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
807 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
808 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
809 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
810 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
811 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
812 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
813 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
814 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
815 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
816 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
817 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
818 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
820 * add more here as they are defined in
821 * include/net/ieee80211_radiotap.h
826 * for every radiotap entry we can at
827 * least skip (by knowing the length)...
830 while (iterator->arg_index < sizeof (rt_sizes))
834 if (!(iterator->bitmap_shifter & 1))
835 goto next_entry; /* arg not present */
838 * arg is present, account for alignment padding
839 * 8-bit args can be at any alignment
840 * 16-bit args must start on 16-bit boundary
841 * 32-bit args must start on 32-bit boundary
842 * 64-bit args must start on 64-bit boundary
844 * note that total arg size can differ from alignment of
845 * elements inside arg, so we use upper nybble of length
846 * table to base alignment on
848 * also note: these alignments are ** relative to the
849 * start of the radiotap header **. There is no guarantee
850 * that the radiotap header itself is aligned on any
854 if ((((void *) iterator->arg) -
855 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
857 iterator->arg_index +=
858 (rt_sizes[iterator->arg_index] >> 4) -
859 ((((void *) iterator->arg) -
860 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
864 * this is what we will return to user, but we need to
865 * move on first so next call has something fresh to test
868 iterator->this_arg_index = iterator->arg_index;
869 iterator->this_arg = iterator->arg;
872 /* internally move on the size of this arg */
874 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
877 * check for insanity where we are given a bitmap that
878 * claims to have more arg content than the length of the
879 * radiotap section. We will normally end up equalling this
880 * max_length on the last arg, never exceeding it.
883 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
884 iterator->max_length)
889 iterator->arg_index++;
890 if (((iterator->arg_index & 31) == 0))
892 /* completed current uint32_t bitmap */
893 if (iterator->bitmap_shifter & 1)
895 /* b31 was set, there is more */
896 /* move to next uint32_t bitmap */
897 iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
898 iterator->next_bitmap++;
902 /* no more bitmaps: end */
903 iterator->arg_index = sizeof (rt_sizes);
907 { /* just try the next bit */
908 iterator->bitmap_shifter >>= 1;
911 /* if we found a valid arg earlier, return it now */
914 return iterator->this_arg_index;
918 /* we don't know how to handle any more args, we're done */
924 * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
925 * @param buffer pointer to buffer for the message
926 * @param mac pointer to the mac address
927 * @return number of bytes written
930 send_mac_to_plugin (char *buffer, struct MacAddress *mac)
932 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
934 memcpy (&macmsg.mac, (char *) mac, sizeof (struct MacAddress));
935 macmsg.hdr.size = htons (sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
936 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
937 memcpy (buffer, &macmsg, sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
938 return sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage);
943 * Return the channel from the frequency (in Mhz)
944 * @param frequency of the channel
945 * @return number of the channel
948 get_channel_from_frequency (int frequency)
950 if (frequency >= 2412 && frequency <= 2472)
951 return (frequency - 2407) / 5;
952 if (frequency == 2484)
954 if (frequency >= 5000 && frequency <= 6100)
955 return (frequency - 5000) / 5;
961 * function to calculate the crc, the start of the calculation
962 * @param buf buffer to calc the crc
963 * @param len len of the buffer
967 calc_crc_osdep (const unsigned char *buf, size_t len)
969 static const unsigned long int crc_tbl_osdep[256] = {
970 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
971 0xE963A535, 0x9E6495A3,
972 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
973 0xE7B82D07, 0x90BF1D91,
974 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
975 0xF4D4B551, 0x83D385C7,
976 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
977 0xFA0F3D63, 0x8D080DF5,
978 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
979 0xD20D85FD, 0xA50AB56B,
980 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
981 0xDCD60DCF, 0xABD13D59,
982 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
983 0xCFBA9599, 0xB8BDA50F,
984 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
985 0xC1611DAB, 0xB6662D3D,
986 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
987 0x9FBFE4A5, 0xE8B8D433,
988 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
989 0x91646C97, 0xE6635C01,
990 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
991 0x8208F4C1, 0xF50FC457,
992 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
993 0x8CD37CF3, 0xFBD44C65,
994 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
995 0xA4D1C46D, 0xD3D6F4FB,
996 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
997 0xAA0A4C5F, 0xDD0D7CC9,
998 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
999 0xB966D409, 0xCE61E49F,
1000 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1001 0xB7BD5C3B, 0xC0BA6CAD,
1002 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1003 0x04DB2615, 0x73DC1683,
1004 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1005 0x0A00AE27, 0x7D079EB1,
1006 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1007 0x196C3671, 0x6E6B06E7,
1008 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1009 0x17B7BE43, 0x60B08ED5,
1010 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1011 0x3FB506DD, 0x48B2364B,
1012 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1013 0x316E8EEF, 0x4669BE79,
1014 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1015 0x220216B9, 0x5505262F,
1016 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1017 0x2CD99E8B, 0x5BDEAE1D,
1018 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1019 0x72076785, 0x05005713,
1020 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1021 0x7CDCEFB7, 0x0BDBDF21,
1022 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1023 0x6FB077E1, 0x18B74777,
1024 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1025 0x616BFFD3, 0x166CCF45,
1026 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1027 0x4969474D, 0x3E6E77DB,
1028 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1029 0x47B2CF7F, 0x30B5FFE9,
1030 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1031 0x54DE5729, 0x23D967BF,
1032 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1033 0x5A05DF1B, 0x2D02EF8D
1036 unsigned long crc = 0xFFFFFFFF;
1038 for (; len > 0; len--, buf++)
1039 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1045 * Function to check crc of the wlan packet
1046 * @param buf buffer of the packet
1047 * @param len len of the data
1048 * @return crc sum of the data
1051 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1058 crc = calc_crc_osdep (buf, len);
1060 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1061 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
1066 * function to get the channel of a specific wlan card
1067 * @param dev pointer to the dev struct of the card
1068 * @return channel number
1071 linux_get_channel (const struct HardwareInfos *dev)
1078 memset (&wrq, 0, sizeof (struct iwreq));
1079 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1081 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1084 frequency = wrq.u.freq.m;
1085 if (100000000 < frequency)
1086 frequency /= 100000;
1087 else if (1000000 < frequency)
1089 if (1000 < frequency)
1090 chan = get_channel_from_frequency (frequency);
1098 * function to read from a wlan card
1099 * @param dev pointer to the struct of the wlan card
1100 * @param buf buffer to read to
1101 * @param buf_size size of the buffer
1102 * @param ri radiotap_rx info
1103 * @return size read from the buffer
1106 linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1107 struct Radiotap_rx *ri)
1109 unsigned char tmpbuf[buf_size];
1111 int n, got_signal, got_noise, got_channel, fcs_removed;
1113 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1115 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1118 if (EAGAIN == errno)
1120 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1124 memset (buf, 0, buf_size);
1125 memset (ri, 0, sizeof (*ri));
1127 switch (dev->arptype_in)
1129 case ARPHRD_IEEE80211_PRISM:
1131 /* skip the prism header */
1132 if (tmpbuf[7] == 0x40)
1134 /* prism54 uses a different format */
1135 ri->ri_power = tmpbuf[0x33];
1136 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
1137 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
1144 ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48);
1145 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
1146 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
1147 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
1148 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
1152 n = *(int *) (tmpbuf + 4);
1155 if ( (n < 8) || (n >= caplen) )
1160 case ARPHRD_IEEE80211_FULL:
1162 struct ieee80211_radiotap_iterator iterator;
1163 struct ieee80211_radiotap_header *rthdr;
1165 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1167 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
1170 /* go through the radiotap arguments we have been given
1174 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1177 switch (iterator.this_arg_index)
1180 case IEEE80211_RADIOTAP_TSFT:
1181 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1184 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1187 if (*iterator.this_arg < 127)
1188 ri->ri_power = *iterator.this_arg;
1190 ri->ri_power = *iterator.this_arg - 255;
1196 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1199 if (*iterator.this_arg < 127)
1200 ri->ri_power = *iterator.this_arg;
1202 ri->ri_power = *iterator.this_arg - 255;
1208 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1211 if (*iterator.this_arg < 127)
1212 ri->ri_noise = *iterator.this_arg;
1214 ri->ri_noise = *iterator.this_arg - 255;
1220 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1223 if (*iterator.this_arg < 127)
1224 ri->ri_noise = *iterator.this_arg;
1226 ri->ri_noise = *iterator.this_arg - 255;
1232 case IEEE80211_RADIOTAP_ANTENNA:
1233 ri->ri_antenna = *iterator.this_arg;
1236 case IEEE80211_RADIOTAP_CHANNEL:
1237 ri->ri_channel = *iterator.this_arg;
1241 case IEEE80211_RADIOTAP_RATE:
1242 ri->ri_rate = (*iterator.this_arg) * 500000;
1245 case IEEE80211_RADIOTAP_FLAGS:
1246 /* is the CRC visible at the end?
1249 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1255 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1261 n = GNUNET_le16toh (rthdr->it_len);
1262 if (n <= 0 || n >= caplen)
1266 case ARPHRD_IEEE80211:
1276 //detect fcs at the end, even if the flag wasn't set and remove it
1277 if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
1281 memcpy (buf, tmpbuf + n, caplen);
1283 ri->ri_channel = linux_get_channel (dev);
1290 * function to open the device for read/write
1291 * @param dev pointer to the device struct
1292 * @return 0 on success
1295 open_device_raw (struct HardwareInfos *dev)
1299 struct packet_mreq mr;
1300 struct sockaddr_ll sll;
1302 /* find the interface index */
1303 memset (&ifr, 0, sizeof (ifr));
1304 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1305 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1307 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1308 IFNAMSIZ, dev->iface, strerror (errno));
1312 /* lookup the hardware type */
1313 memset (&sll, 0, sizeof (sll));
1314 sll.sll_family = AF_PACKET;
1315 sll.sll_ifindex = ifr.ifr_ifindex;
1316 sll.sll_protocol = htons (ETH_P_ALL);
1317 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1319 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1320 IFNAMSIZ, dev->iface, strerror (errno));
1324 /* lookup iw mode */
1325 memset (&wrq, 0, sizeof (struct iwreq));
1326 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1327 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1329 /* most probably not supported (ie for rtap ipw interface) *
1330 * so just assume its correctly set... */
1331 wrq.u.mode = IW_MODE_MONITOR;
1334 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1335 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1336 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
1337 (wrq.u.mode != IW_MODE_MONITOR))
1339 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1340 IFNAMSIZ, dev->iface);
1344 /* Is interface st to up, broadcast & running ? */
1345 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1347 /* Bring interface up */
1348 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1350 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1352 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1353 IFNAMSIZ, dev->iface, strerror (errno));
1358 /* bind the raw socket to the interface */
1359 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1361 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1362 dev->iface, strerror (errno));
1366 /* lookup the hardware type */
1367 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1369 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1370 IFNAMSIZ, dev->iface, strerror (errno));
1374 memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1375 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1376 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1377 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1378 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1380 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1381 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1385 /* enable promiscuous mode */
1386 memset (&mr, 0, sizeof (mr));
1387 mr.mr_ifindex = sll.sll_ifindex;
1388 mr.mr_type = PACKET_MR_PROMISC;
1390 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1393 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1394 IFNAMSIZ, dev->iface);
1403 * function to prepare the helper, e.g. sockets, device...
1404 * @param dev struct for the device
1405 * @param iface name of the interface
1406 * @return 0 on success
1409 wlan_initialize (struct HardwareInfos *dev, const char *iface)
1415 dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1416 if (0 > dev->fd_raw)
1418 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
1421 if (dev->fd_raw >= FD_SETSIZE)
1423 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1424 dev->fd_raw, FD_SETSIZE);
1425 close (dev->fd_raw);
1429 /* mac80211 stack detection */
1431 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1433 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1435 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1436 close (dev->fd_raw);
1439 strncpy (dev->iface, iface, IFNAMSIZ);
1440 if (0 != open_device_raw (dev))
1442 close (dev->fd_raw);
1450 * Function to test incoming packets mac for being our own.
1452 * @param uint8_taIeeeHeader buffer of the packet
1453 * @param dev the Hardware_Infos struct
1454 * @return 0 if mac belongs to us, 1 if mac is for another target
1457 mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1458 const struct HardwareInfos *dev)
1460 if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1462 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1464 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
1471 * function to set the wlan header to make attacks more difficult
1472 * @param uint8_taIeeeHeader pointer to the header of the packet
1473 * @param dev pointer to the Hardware_Infos struct
1476 mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1477 const struct HardwareInfos *dev)
1479 uint8_taIeeeHeader->i_fc[0] = 0x08;
1480 uint8_taIeeeHeader->i_fc[1] = 0x00;
1481 memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE);
1482 memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE);
1487 * function to process the data from the stdin
1488 * @param cls pointer to the device struct
1489 * @param hdr pointer to the start of the packet
1492 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1494 struct HardwareInfos *dev = cls;
1495 struct SendBuffer *write_pout = &dev->write_pout;
1496 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
1497 struct ieee80211_frame *wlanheader;
1499 struct RadioTapheader rtheader;
1501 rtheader.header.it_version = 0; /* radiotap version */
1502 rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */
1503 rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap */
1504 rtheader.rate = 0x00;
1505 rtheader.pad1 = 0x00;
1507 GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1509 sendsize = ntohs (hdr->size);
1511 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1513 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
1517 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1519 if (MAXLINE < sendsize)
1521 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1524 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1526 fprintf (stderr, "Function stdin_send_hw: wrong packet type\n");
1530 rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
1531 rtheader.rate = header->rate;
1532 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
1533 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
1534 /* payload contains MAC address, but we don't trust it, so we'll
1535 * overwrite it with OUR MAC address again to prevent mischief */
1536 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
1537 mac_set (wlanheader, dev);
1538 write_pout->size = sendsize + sizeof (rtheader);
1543 * main function of the helper
1544 * @param argc number of arguments
1545 * @param argv arguments
1546 * @return 0 on success, 1 on error
1549 main (int argc, char *argv[])
1552 struct HardwareInfos dev;
1553 char readbuf[MAXLINE];
1554 struct SendBuffer write_std;
1561 struct MessageStreamTokenizer *stdin_mst;
1566 "You must specify the name of the interface as the first and only argument to this program.\n");
1569 if (0 != wlan_initialize (&dev, argv[1]))
1572 if (0 != setresuid (uid, uid, uid))
1574 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1575 /* not critical, continue anyway */
1578 dev.write_pout.size = 0;
1579 dev.write_pout.pos = 0;
1580 stdin_mst = mst_create (&stdin_send_hw, &dev);
1582 /* send mac to STDOUT first */
1584 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac);
1591 if ((0 == dev.write_pout.size) && (1 == stdin_open))
1593 FD_SET (STDIN_FILENO, &rfds);
1594 maxfd = MAX (maxfd, STDIN_FILENO);
1596 if (0 == write_std.size)
1598 FD_SET (dev.fd_raw, &rfds);
1599 maxfd = MAX (maxfd, dev.fd_raw);
1602 if (0 < write_std.size)
1604 FD_SET (STDOUT_FILENO, &wfds);
1605 maxfd = MAX (maxfd, STDOUT_FILENO);
1607 if (0 < dev.write_pout.size)
1609 FD_SET (dev.fd_raw, &wfds);
1610 maxfd = MAX (maxfd, dev.fd_raw);
1612 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1613 if ((-1 == retval) && (EINTR == errno))
1617 fprintf (stderr, "select failed: %s\n", strerror (errno));
1620 if (FD_ISSET (STDOUT_FILENO, &wfds))
1623 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1624 write_std.size - write_std.pos);
1627 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1630 write_std.pos += ret;
1631 if (write_std.pos == write_std.size)
1637 if (FD_ISSET (dev.fd_raw, &wfds))
1639 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
1642 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1646 dev.write_pout.pos += ret;
1647 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
1649 /* we should not get partial sends with packet-oriented devices... */
1650 fprintf (stderr, "Write error, partial send: %u/%u\n",
1651 dev.write_pout.pos, dev.write_pout.size);
1654 if (dev.write_pout.pos == dev.write_pout.size)
1656 dev.write_pout.pos = 0;
1657 dev.write_pout.size = 0;
1661 if (FD_ISSET (STDIN_FILENO, &rfds))
1663 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
1666 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1671 /* stop reading... */
1674 mst_receive (stdin_mst, readbuf, ret);
1677 if (FD_ISSET (dev.fd_raw, &rfds))
1679 struct GNUNET_MessageHeader *header;
1680 struct Radiotap_rx *rxinfo;
1681 struct ieee80211_frame *datastart;
1683 header = (struct GNUNET_MessageHeader *) write_std.buf;
1684 rxinfo = (struct Radiotap_rx *) &header[1];
1685 datastart = (struct ieee80211_frame *) &rxinfo[1];
1687 linux_read (&dev, (unsigned char *) datastart,
1688 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1689 sizeof (struct GNUNET_MessageHeader), rxinfo);
1692 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1695 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1698 ret + sizeof (struct GNUNET_MessageHeader) +
1699 sizeof (struct Radiotap_rx);
1700 header->size = htons (write_std.size);
1701 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1706 /* Error handling, try to clean up a bit at least */
1707 mst_destroy (stdin_mst);
1709 return 1; /* we never exit 'normally' */
1712 /* end of gnunet-helper-transport-wlan.c */