aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-helper-transport-wlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-helper-transport-wlan.c')
-rw-r--r--src/transport/gnunet-helper-transport-wlan.c1712
1 files changed, 1712 insertions, 0 deletions
diff --git a/src/transport/gnunet-helper-transport-wlan.c b/src/transport/gnunet-helper-transport-wlan.c
new file mode 100644
index 000000000..0bc6d88ff
--- /dev/null
+++ b/src/transport/gnunet-helper-transport-wlan.c
@@ -0,0 +1,1712 @@
1/*
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
6
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.
11
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.
16
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.
21*/
22/*-
23 * we use our local copy of ieee80211_radiotap.h
24 *
25 * - since we can't support extensions we don't understand
26 * - since linux does not include it in userspace headers
27 *
28 * Portions of this code were taken from the ieee80211_radiotap.h header,
29 * which is
30 *
31 * Copyright (c) 2003, 2004 David Young. All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
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
43 * written permission.
44 *
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
56 * OF SUCH DAMAGE.
57 */
58
59/*
60 * Modifications to fit into the linux IEEE 802.11 stack,
61 * Mike Kershaw (dragorn@kismetwireless.net)
62 */
63
64/**
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
69 *
70 * This program serves as the mediator between the wlan interface and
71 * gnunet
72 */
73
74/**
75 * parts taken from aircrack-ng, parts changend.
76 */
77#define _GNU_SOURCE
78#include <sys/socket.h>
79#include <sys/ioctl.h>
80#include <sys/types.h>
81#include <unistd.h>
82#include <sys/wait.h>
83#include <sys/time.h>
84#include <sys/stat.h>
85#include <netpacket/packet.h>
86#include <linux/if_ether.h>
87#include <linux/if.h>
88#include <linux/wireless.h>
89#include <netinet/in.h>
90#include <linux/if_tun.h>
91#include <stdio.h>
92#include <stdlib.h>
93#include <string.h>
94#include <stdarg.h>
95#include <fcntl.h>
96#include <errno.h>
97#include <dirent.h>
98#include <sys/param.h>
99#include <unistd.h>
100#include <stdint.h>
101
102#include "gnunet_protocols.h"
103#include "plugin_transport_wlan.h"
104
105#define ARPHRD_IEEE80211 801
106#define ARPHRD_IEEE80211_PRISM 802
107#define ARPHRD_IEEE80211_FULL 803
108
109/**
110 * size of 802.11 address
111 */
112#define IEEE80211_ADDR_LEN 6
113
114#define MAXLINE 4096
115
116#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
117
118
119/* Name Data type Units
120 * ---- --------- -----
121 *
122 * IEEE80211_RADIOTAP_TSFT __le64 microseconds
123 *
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.
127 *
128 * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
129 *
130 * Tx/Rx frequency in MHz, followed by flags (see below).
131 *
132 * IEEE80211_RADIOTAP_FHSS __le16 see below
133 *
134 * For frequency-hopping radios, the hop set (first byte)
135 * and pattern (second byte).
136 *
137 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s
138 *
139 * Tx/Rx data rate
140 *
141 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
142 * one milliwatt (dBm)
143 *
144 * RF signal power at the antenna, decibel difference from
145 * one milliwatt.
146 *
147 * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
148 * one milliwatt (dBm)
149 *
150 * RF noise power at the antenna, decibel difference from one
151 * milliwatt.
152 *
153 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
154 *
155 * RF signal power at the antenna, decibel difference from an
156 * arbitrary, fixed reference.
157 *
158 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
159 *
160 * RF noise power at the antenna, decibel difference from an
161 * arbitrary, fixed reference point.
162 *
163 * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
164 *
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
168 * this?)
169 *
170 * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
171 *
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.
175 *
176 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
177 *
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.
181 *
182 * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
183 * one milliwatt (dBm)
184 *
185 * Transmit power expressed as dBm (decibels from a 1 milliwatt
186 * reference). This is the absolute power level measured at
187 * the antenna port.
188 *
189 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
190 *
191 * Properties of transmitted and received frames. See flags
192 * defined below.
193 *
194 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
195 *
196 * Unitless indication of the Rx/Tx antenna for this packet.
197 * The first antenna is antenna 0.
198 *
199 * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
200 *
201 * Properties of received frames. See flags defined below.
202 *
203 * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
204 *
205 * Properties of transmitted frames. See flags defined below.
206 *
207 * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data
208 *
209 * Number of rts retries a transmitted frame used.
210 *
211 * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data
212 *
213 * Number of unicast retries a transmitted frame used.
214 *
215 */
216enum RadiotapType
217{
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
237};
238
239/* For IEEE80211_RADIOTAP_FLAGS */
240#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
241 * during CFP
242 */
243#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
244 * with short
245 * preamble
246 */
247#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
248 * with WEP encryption
249 */
250#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
251 * with fragmentation
252 */
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)
257 */
258/* For IEEE80211_RADIOTAP_RX_FLAGS */
259#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
260
261/* For IEEE80211_RADIOTAP_TX_FLAGS */
262#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
263 * retries */
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
268 * by userspace */
269
270
271/**
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.
275 *
276 * I suggest the following extensible radio capture format. It is
277 * based on a bitmap indicating which fields are present.
278 *
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
284 * readers.
285 *
286 * The radio capture header precedes the 802.11 header.
287 * All data in the header is little endian on all platforms.
288 */
289struct ieee80211_radiotap_header
290{
291 /**
292 * Version 0. Only increases for drastic changes, introduction of
293 * compatible new fields does not count.
294 */
295 uint8_t it_version;
296 uint8_t it_pad;
297
298 /**
299 * length of the whole header in bytes, including it_version,
300 * it_pad, it_len, and data fields.
301 */
302 uint16_t it_len;
303
304 /**
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.
308 */
309 uint32_t it_present;
310};
311
312struct RadioTapheader
313{
314 struct ieee80211_radiotap_header header;
315 uint8_t rate;
316 uint8_t pad1;
317 uint16_t txflags;
318};
319
320
321/**
322 * FIXME.
323 */
324struct SendBuffer
325{
326 unsigned int pos;
327 unsigned int size;
328 char buf[MAXLINE * 2];
329};
330
331
332/**
333 * generic definitions for IEEE 802.11 frames
334 */
335struct ieee80211_frame
336{
337 uint8_t i_fc[2];
338 uint8_t i_dur[2];
339 uint8_t i_addr1[IEEE80211_ADDR_LEN];
340 uint8_t i_addr2[IEEE80211_ADDR_LEN];
341 uint8_t i_addr3[IEEE80211_ADDR_LEN];
342 uint8_t i_seq[2];
343 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
344 /* see below */
345} GNUNET_PACKED;
346
347
348/**
349 * struct for storing the information of the hardware
350 */
351struct HardwareInfos
352{
353
354 /**
355 * send buffer
356 */
357 struct SendBuffer write_pout;
358
359 /**
360 * file descriptor for the raw socket
361 */
362 int fd_raw;
363
364 int arptype_in;
365
366 /**
367 * Name of the interface, not necessarily 0-terminated (!).
368 */
369 char iface[IFNAMSIZ];
370
371 struct MacAddress pl_mac;
372};
373
374
375
376
377 /* *INDENT-OFF* */
378#define ___my_swab16(x) \
379((u_int16_t)( \
380 (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \
381 (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) ))
382
383#define ___my_swab32(x) \
384((u_int32_t)( \
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) \
390((u_int64_t)( \
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) ))
399 /* *INDENT-ON* */
400
401
402/**
403 * struct ieee80211_radiotap_iterator - tracks walk through present radiotap args
404 */
405struct ieee80211_radiotap_iterator
406{
407 /**
408 * pointer to the radiotap header we are walking through
409 */
410 const struct ieee80211_radiotap_header *rtheader;
411
412 /**
413 * length of radiotap header in cpu byte ordering
414 */
415 size_t max_length;
416
417 /**
418 * IEEE80211_RADIOTAP_... index of current arg
419 */
420 unsigned int this_arg_index;
421
422 /**
423 * pointer to current radiotap arg
424 */
425 uint8_t *this_arg;
426
427 /**
428 * internal next argument index
429 */
430 unsigned int arg_index;
431
432 /**
433 * internal next argument pointer
434 */
435 uint8_t *arg;
436
437 /**
438 * internal pointer to next present uint32_t
439 */
440 uint32_t *next_bitmap;
441
442 /**
443 * internal shifter for curr uint32_t bitmap, b0 set == arg present
444 */
445 uint32_t bitmap_shifter;
446};
447
448
449
450/* specialized version of server_mst.c begins here */
451
452#define ALIGN_FACTOR 8
453
454/**
455 * Smallest supported message.
456 */
457#define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
458
459
460/**
461 * Functions with this signature are called whenever a
462 * complete message is received by the tokenizer.
463 *
464 * @param cls closure
465 * @param message the actual message
466 */
467typedef void (*MessageTokenizerCallback) (void *cls,
468 const struct
469 GNUNET_MessageHeader *
470 message);
471
472/**
473 * Handle to a message stream tokenizer.
474 */
475struct MessageStreamTokenizer
476{
477
478 /**
479 * Function to call on completed messages.
480 */
481 MessageTokenizerCallback cb;
482
483 /**
484 * Closure for cb.
485 */
486 void *cb_cls;
487
488 /**
489 * Size of the buffer (starting at 'hdr').
490 */
491 size_t curr_buf;
492
493 /**
494 * How many bytes in buffer have we already processed?
495 */
496 size_t off;
497
498 /**
499 * How many bytes in buffer are valid right now?
500 */
501 size_t pos;
502
503 /**
504 * Beginning of the buffer. Typed like this to force alignment.
505 */
506 struct GNUNET_MessageHeader *hdr;
507
508};
509
510
511
512/**
513 * Create a message stream tokenizer.
514 *
515 * @param cb function to call on completed messages
516 * @param cb_cls closure for cb
517 * @return handle to tokenizer
518 */
519static struct MessageStreamTokenizer *
520mst_create (MessageTokenizerCallback cb,
521 void *cb_cls)
522{
523 struct MessageStreamTokenizer *ret;
524
525 ret = malloc (sizeof (struct MessageStreamTokenizer));
526 if (NULL == ret)
527 exit (1);
528 ret->hdr = malloc (MIN_BUFFER_SIZE);
529 if (NULL == ret->hdr)
530 exit (2);
531 ret->curr_buf = MIN_BUFFER_SIZE;
532 ret->cb = cb;
533 ret->cb_cls = cb_cls;
534 return ret;
535}
536
537
538/**
539 * Add incoming data to the receive buffer and call the
540 * callback for all complete messages.
541 *
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
547 */
548static int
549mst_receive (struct MessageStreamTokenizer *mst,
550 const char *buf, size_t size)
551{
552 const struct GNUNET_MessageHeader *hdr;
553 size_t delta;
554 uint16_t want;
555 char *ibuf;
556 int need_align;
557 unsigned long offset;
558 int ret;
559
560 ret = GNUNET_OK;
561 ibuf = (char *) mst->hdr;
562 while (mst->pos > 0)
563 {
564do_align:
565 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
566 (0 != (mst->off % ALIGN_FACTOR)))
567 {
568 /* need to align or need more space */
569 mst->pos -= mst->off;
570 memmove (ibuf, &ibuf[mst->off], mst->pos);
571 mst->off = 0;
572 }
573 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
574 {
575 delta =
576 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
577 (mst->pos - mst->off), size);
578 memcpy (&ibuf[mst->pos], buf, delta);
579 mst->pos += delta;
580 buf += delta;
581 size -= delta;
582 }
583 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
584 {
585 return GNUNET_OK;
586 }
587 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
588 want = ntohs (hdr->size);
589 if (want < sizeof (struct GNUNET_MessageHeader))
590 {
591 // GNUNET_break_op (0);
592 return GNUNET_SYSERR;
593 }
594 if (mst->curr_buf - mst->off < want)
595 {
596 /* need more space */
597 mst->pos -= mst->off;
598 memmove (ibuf, &ibuf[mst->off], mst->pos);
599 mst->off = 0;
600 }
601 if (want > mst->curr_buf)
602 {
603 mst->hdr = realloc (mst->hdr, want);
604 if (NULL == mst->hdr)
605 exit (3);
606 ibuf = (char *) mst->hdr;
607 mst->curr_buf = want;
608 }
609 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
610 if (mst->pos - mst->off < want)
611 {
612 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
613 memcpy (&ibuf[mst->pos], buf, delta);
614 mst->pos += delta;
615 buf += delta;
616 size -= delta;
617 }
618 if (mst->pos - mst->off < want)
619 {
620 return GNUNET_OK;
621 }
622 mst->cb (mst->cb_cls, hdr);
623 mst->off += want;
624 if (mst->off == mst->pos)
625 {
626 /* reset to beginning of buffer, it's free right now! */
627 mst->off = 0;
628 mst->pos = 0;
629 }
630 }
631 while (size > 0)
632 {
633 if (size < sizeof (struct GNUNET_MessageHeader))
634 break;
635 offset = (unsigned long) buf;
636 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
637 if (GNUNET_NO == need_align)
638 {
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))
643 {
644 // GNUNET_break_op (0);
645 mst->off = 0;
646 return GNUNET_SYSERR;
647 }
648 if (size < want)
649 break; /* or not, buffer incomplete, so copy to private buffer... */
650 mst->cb (mst->cb_cls, hdr);
651 buf += want;
652 size -= want;
653 }
654 else
655 {
656 /* need to copy to private buffer to align;
657 * yes, we go a bit more spagetti than usual here */
658 goto do_align;
659 }
660 }
661 if (size > 0)
662 {
663 if (size + mst->pos > mst->curr_buf)
664 {
665 mst->hdr = realloc (mst->hdr, size + mst->pos);
666 if (NULL == mst->hdr)
667 exit (4);
668 ibuf = (char *) mst->hdr;
669 mst->curr_buf = size + mst->pos;
670 }
671 // GNUNET_assert (mst->pos + size <= mst->curr_buf);
672 memcpy (&ibuf[mst->pos], buf, size);
673 mst->pos += size;
674 }
675 return ret;
676}
677
678
679/**
680 * Destroys a tokenizer.
681 *
682 * @param mst tokenizer to destroy
683 */
684static void
685mst_destroy (struct MessageStreamTokenizer *mst)
686{
687 free (mst->hdr);
688 free (mst);
689}
690
691/* end of server_mst.c copy */
692
693
694
695
696/**
697 * Radiotap header iteration
698 *
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.
707 *
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
712 */
713static int
714ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
715 const struct ieee80211_radiotap_header
716 *radiotap_header,
717 size_t max_length)
718{
719 if ( (iterator == NULL) ||
720 (radiotap_header == NULL) )
721 return -EINVAL;
722
723 /* Linux only supports version 0 radiotap format */
724 if (0 != radiotap_header->it_version)
725 return -EINVAL;
726
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))) )
730 return -EINVAL;
731
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);
736 iterator->arg =
737 ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header);
738 iterator->this_arg = 0;
739
740 /* find payload start allowing for extended bitmap(s) */
741 if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
742 {
743 while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) &
744 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
745 {
746 iterator->arg += sizeof (uint32_t);
747
748 /*
749 * check for insanity where the present bitmaps
750 * keep claiming to extend up to or even beyond the
751 * stated radiotap header length
752 */
753 if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
754 return -EINVAL;
755 }
756 iterator->arg += sizeof (uint32_t);
757 /*
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
761 */
762 }
763 /* we are all initialized happily */
764 return 0;
765}
766
767
768/**
769 * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
770 *
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
775 * format.
776 *
777 * @param iterator: radiotap_iterator to move to next arg (if any)
778 *
779 * @return next present arg index on success or negative if no more or error
780 */
781static int
782ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
783{
784
785 /*
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
789 *
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.
795 *
796 * upper nybble: content alignment for arg
797 * lower nybble: content length for arg
798 */
799
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
819 /*
820 * add more here as they are defined in
821 * include/net/ieee80211_radiotap.h
822 */
823 };
824
825 /*
826 * for every radiotap entry we can at
827 * least skip (by knowing the length)...
828 */
829
830 while (iterator->arg_index < sizeof (rt_sizes))
831 {
832 int hit = 0;
833
834 if (!(iterator->bitmap_shifter & 1))
835 goto next_entry; /* arg not present */
836
837 /*
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
843 *
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
847 *
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
851 * kind of boundary.
852 */
853
854 if ((((void *) iterator->arg) -
855 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4)
856 - 1))
857 iterator->arg_index +=
858 (rt_sizes[iterator->arg_index] >> 4) -
859 ((((void *) iterator->arg) -
860 ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >>
861 4) - 1));
862
863 /*
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
866 */
867
868 iterator->this_arg_index = iterator->arg_index;
869 iterator->this_arg = iterator->arg;
870 hit = 1;
871
872 /* internally move on the size of this arg */
873
874 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
875
876 /*
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.
881 */
882
883 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
884 iterator->max_length)
885 return -EINVAL;
886
887next_entry:
888
889 iterator->arg_index++;
890 if (((iterator->arg_index & 31) == 0))
891 {
892 /* completed current uint32_t bitmap */
893 if (iterator->bitmap_shifter & 1)
894 {
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++;
899 }
900 else
901 {
902 /* no more bitmaps: end */
903 iterator->arg_index = sizeof (rt_sizes);
904 }
905 }
906 else
907 { /* just try the next bit */
908 iterator->bitmap_shifter >>= 1;
909 }
910
911 /* if we found a valid arg earlier, return it now */
912
913 if (hit)
914 return iterator->this_arg_index;
915
916 }
917
918 /* we don't know how to handle any more args, we're done */
919 return -1;
920}
921
922
923/**
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
928 */
929static int
930send_mac_to_plugin (char *buffer, struct MacAddress *mac)
931{
932 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
933
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);
939}
940
941
942/**
943 * Return the channel from the frequency (in Mhz)
944 * @param frequency of the channel
945 * @return number of the channel
946 */
947static int
948get_channel_from_frequency (int frequency)
949{
950 if (frequency >= 2412 && frequency <= 2472)
951 return (frequency - 2407) / 5;
952 if (frequency == 2484)
953 return 14;
954 if (frequency >= 5000 && frequency <= 6100)
955 return (frequency - 5000) / 5;
956 return -1;
957}
958
959
960/**
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
964 * @return crc sum
965 */
966static unsigned long
967calc_crc_osdep (const unsigned char *buf, size_t len)
968{
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
1034 };
1035
1036 unsigned long crc = 0xFFFFFFFF;
1037
1038 for (; len > 0; len--, buf++)
1039 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1040 return (~crc);
1041}
1042
1043
1044/**
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
1049 */
1050static int
1051check_crc_buf_osdep (const unsigned char *buf, size_t len)
1052{
1053 unsigned long crc;
1054
1055 if (0 > len)
1056 return 0;
1057
1058 crc = calc_crc_osdep (buf, len);
1059 buf += len;
1060 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1061 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
1062}
1063
1064
1065/**
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
1069 */
1070static int
1071linux_get_channel (const struct HardwareInfos *dev)
1072{
1073 struct iwreq wrq;
1074 int fd;
1075 int frequency;
1076 int chan;
1077
1078 memset (&wrq, 0, sizeof (struct iwreq));
1079 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1080 fd = dev->fd_raw;
1081 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
1082 return -1;
1083
1084 frequency = wrq.u.freq.m;
1085 if (100000000 < frequency)
1086 frequency /= 100000;
1087 else if (1000000 < frequency)
1088 frequency /= 1000;
1089 if (1000 < frequency)
1090 chan = get_channel_from_frequency (frequency);
1091 else
1092 chan = frequency;
1093 return chan;
1094}
1095
1096
1097/**
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
1104 */
1105static ssize_t
1106linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size,
1107 struct Radiotap_rx *ri)
1108{
1109 unsigned char tmpbuf[buf_size];
1110 ssize_t caplen;
1111 int n, got_signal, got_noise, got_channel, fcs_removed;
1112
1113 n = got_signal = got_noise = got_channel = fcs_removed = 0;
1114
1115 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1116 if (0 > caplen)
1117 {
1118 if (EAGAIN == errno)
1119 return 0;
1120 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1121 return -1;
1122 }
1123
1124 memset (buf, 0, buf_size);
1125 memset (ri, 0, sizeof (*ri));
1126
1127 switch (dev->arptype_in)
1128 {
1129 case ARPHRD_IEEE80211_PRISM:
1130 {
1131 /* skip the prism header */
1132 if (tmpbuf[7] == 0x40)
1133 {
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;
1138 got_signal = 1;
1139 got_noise = 1;
1140 n = 0x40;
1141 }
1142 else
1143 {
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;
1149 got_channel = 1;
1150 got_signal = 1;
1151 got_noise = 1;
1152 n = *(int *) (tmpbuf + 4);
1153 }
1154
1155 if ( (n < 8) || (n >= caplen) )
1156 return 0;
1157 }
1158 break;
1159
1160 case ARPHRD_IEEE80211_FULL:
1161 {
1162 struct ieee80211_radiotap_iterator iterator;
1163 struct ieee80211_radiotap_header *rthdr;
1164
1165 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
1166
1167 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
1168 return 0;
1169
1170 /* go through the radiotap arguments we have been given
1171 * by the driver
1172 */
1173
1174 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
1175 {
1176
1177 switch (iterator.this_arg_index)
1178 {
1179
1180 case IEEE80211_RADIOTAP_TSFT:
1181 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1182 break;
1183
1184 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1185 if (!got_signal)
1186 {
1187 if (*iterator.this_arg < 127)
1188 ri->ri_power = *iterator.this_arg;
1189 else
1190 ri->ri_power = *iterator.this_arg - 255;
1191
1192 got_signal = 1;
1193 }
1194 break;
1195
1196 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1197 if (!got_signal)
1198 {
1199 if (*iterator.this_arg < 127)
1200 ri->ri_power = *iterator.this_arg;
1201 else
1202 ri->ri_power = *iterator.this_arg - 255;
1203
1204 got_signal = 1;
1205 }
1206 break;
1207
1208 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1209 if (!got_noise)
1210 {
1211 if (*iterator.this_arg < 127)
1212 ri->ri_noise = *iterator.this_arg;
1213 else
1214 ri->ri_noise = *iterator.this_arg - 255;
1215
1216 got_noise = 1;
1217 }
1218 break;
1219
1220 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1221 if (!got_noise)
1222 {
1223 if (*iterator.this_arg < 127)
1224 ri->ri_noise = *iterator.this_arg;
1225 else
1226 ri->ri_noise = *iterator.this_arg - 255;
1227
1228 got_noise = 1;
1229 }
1230 break;
1231
1232 case IEEE80211_RADIOTAP_ANTENNA:
1233 ri->ri_antenna = *iterator.this_arg;
1234 break;
1235
1236 case IEEE80211_RADIOTAP_CHANNEL:
1237 ri->ri_channel = *iterator.this_arg;
1238 got_channel = 1;
1239 break;
1240
1241 case IEEE80211_RADIOTAP_RATE:
1242 ri->ri_rate = (*iterator.this_arg) * 500000;
1243 break;
1244
1245 case IEEE80211_RADIOTAP_FLAGS:
1246 /* is the CRC visible at the end?
1247 * remove
1248 */
1249 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
1250 {
1251 fcs_removed = 1;
1252 caplen -= 4;
1253 }
1254
1255 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
1256 return (0);
1257
1258 break;
1259 }
1260 }
1261 n = GNUNET_le16toh (rthdr->it_len);
1262 if (n <= 0 || n >= caplen)
1263 return 0;
1264 }
1265 break;
1266 case ARPHRD_IEEE80211:
1267 /* do nothing? */
1268 break;
1269 default:
1270 errno = ENOTSUP;
1271 return -1;
1272 }
1273
1274 caplen -= n;
1275
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)))
1278 {
1279 caplen -= 4;
1280 }
1281 memcpy (buf, tmpbuf + n, caplen);
1282 if (!got_channel)
1283 ri->ri_channel = linux_get_channel (dev);
1284
1285 return caplen;
1286}
1287
1288
1289/**
1290 * function to open the device for read/write
1291 * @param dev pointer to the device struct
1292 * @return 0 on success
1293 */
1294static int
1295open_device_raw (struct HardwareInfos *dev)
1296{
1297 struct ifreq ifr;
1298 struct iwreq wrq;
1299 struct packet_mreq mr;
1300 struct sockaddr_ll sll;
1301
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))
1306 {
1307 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1308 IFNAMSIZ, dev->iface, strerror (errno));
1309 return 1;
1310 }
1311
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))
1318 {
1319 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1320 IFNAMSIZ, dev->iface, strerror (errno));
1321 return 1;
1322 }
1323
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))
1328 {
1329 /* most probably not supported (ie for rtap ipw interface) *
1330 * so just assume its correctly set... */
1331 wrq.u.mode = IW_MODE_MONITOR;
1332 }
1333
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))
1338 {
1339 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
1340 IFNAMSIZ, dev->iface);
1341 return 1;
1342 }
1343
1344 /* Is interface st to up, broadcast & running ? */
1345 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1346 {
1347 /* Bring interface up */
1348 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1349
1350 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1351 {
1352 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1353 IFNAMSIZ, dev->iface, strerror (errno));
1354 return 1;
1355 }
1356 }
1357
1358 /* bind the raw socket to the interface */
1359 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1360 {
1361 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1362 dev->iface, strerror (errno));
1363 return 1;
1364 }
1365
1366 /* lookup the hardware type */
1367 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1368 {
1369 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1370 IFNAMSIZ, dev->iface, strerror (errno));
1371 return 1;
1372 }
1373
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))
1379 {
1380 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1381 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1382 return 1;
1383 }
1384
1385 /* enable promiscuous mode */
1386 memset (&mr, 0, sizeof (mr));
1387 mr.mr_ifindex = sll.sll_ifindex;
1388 mr.mr_type = PACKET_MR_PROMISC;
1389 if (0 !=
1390 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1391 sizeof (mr)))
1392 {
1393 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
1394 IFNAMSIZ, dev->iface);
1395 return 1;
1396 }
1397
1398 return 0;
1399}
1400
1401
1402/**
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
1407 */
1408static int
1409wlan_initialize (struct HardwareInfos *dev, const char *iface)
1410{
1411 char strbuf[512];
1412 struct stat sbuf;
1413 int ret;
1414
1415 dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1416 if (0 > dev->fd_raw)
1417 {
1418 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
1419 return 1;
1420 }
1421 if (dev->fd_raw >= FD_SETSIZE)
1422 {
1423 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1424 dev->fd_raw, FD_SETSIZE);
1425 close (dev->fd_raw);
1426 return 1;
1427 }
1428
1429 /* mac80211 stack detection */
1430 ret =
1431 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
1432 iface);
1433 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1434 {
1435 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
1436 close (dev->fd_raw);
1437 return 1;
1438 }
1439 strncpy (dev->iface, iface, IFNAMSIZ);
1440 if (0 != open_device_raw (dev))
1441 {
1442 close (dev->fd_raw);
1443 return 1;
1444 }
1445 return 0;
1446}
1447
1448
1449/**
1450 * Function to test incoming packets mac for being our own.
1451 *
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
1455 */
1456static int
1457mac_test (const struct ieee80211_frame *uint8_taIeeeHeader,
1458 const struct HardwareInfos *dev)
1459{
1460 if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1461 return 1;
1462 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE))
1463 return 0;
1464 if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
1465 return 0;
1466 return 1;
1467}
1468
1469
1470/**
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
1474 */
1475static void
1476mac_set (struct ieee80211_frame *uint8_taIeeeHeader,
1477 const struct HardwareInfos *dev)
1478{
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);
1483}
1484
1485
1486/**
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
1490 */
1491static void
1492stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1493{
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;
1498 size_t sendsize;
1499 struct RadioTapheader rtheader;
1500
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;
1506 rtheader.txflags =
1507 GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1508
1509 sendsize = ntohs (hdr->size);
1510 if (sendsize <
1511 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
1512 {
1513 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
1514 exit (1);
1515 }
1516 sendsize -=
1517 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
1518
1519 if (MAXLINE < sendsize)
1520 {
1521 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
1522 exit (1);
1523 }
1524 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
1525 {
1526 fprintf (stderr, "Function stdin_send_hw: wrong packet type\n");
1527 exit (1);
1528 }
1529
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);
1539}
1540
1541
1542/**
1543 * main function of the helper
1544 * @param argc number of arguments
1545 * @param argv arguments
1546 * @return 0 on success, 1 on error
1547 */
1548int
1549main (int argc, char *argv[])
1550{
1551 uid_t uid;
1552 struct HardwareInfos dev;
1553 char readbuf[MAXLINE];
1554 struct SendBuffer write_std;
1555 ssize_t ret;
1556 int maxfd;
1557 fd_set rfds;
1558 fd_set wfds;
1559 int retval;
1560 int stdin_open;
1561 struct MessageStreamTokenizer *stdin_mst;
1562
1563 if (2 != argc)
1564 {
1565 fprintf (stderr,
1566 "You must specify the name of the interface as the first and only argument to this program.\n");
1567 return 1;
1568 }
1569 if (0 != wlan_initialize (&dev, argv[1]))
1570 return 1;
1571 uid = getuid ();
1572 if (0 != setresuid (uid, uid, uid))
1573 {
1574 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1575 /* not critical, continue anyway */
1576 }
1577
1578 dev.write_pout.size = 0;
1579 dev.write_pout.pos = 0;
1580 stdin_mst = mst_create (&stdin_send_hw, &dev);
1581
1582 /* send mac to STDOUT first */
1583 write_std.pos = 0;
1584 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac);
1585 stdin_open = 1;
1586
1587 while (1)
1588 {
1589 maxfd = -1;
1590 FD_ZERO (&rfds);
1591 if ((0 == dev.write_pout.size) && (1 == stdin_open))
1592 {
1593 FD_SET (STDIN_FILENO, &rfds);
1594 maxfd = MAX (maxfd, STDIN_FILENO);
1595 }
1596 if (0 == write_std.size)
1597 {
1598 FD_SET (dev.fd_raw, &rfds);
1599 maxfd = MAX (maxfd, dev.fd_raw);
1600 }
1601 FD_ZERO (&wfds);
1602 if (0 < write_std.size)
1603 {
1604 FD_SET (STDOUT_FILENO, &wfds);
1605 maxfd = MAX (maxfd, STDOUT_FILENO);
1606 }
1607 if (0 < dev.write_pout.size)
1608 {
1609 FD_SET (dev.fd_raw, &wfds);
1610 maxfd = MAX (maxfd, dev.fd_raw);
1611 }
1612 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1613 if ((-1 == retval) && (EINTR == errno))
1614 continue;
1615 if (0 > retval)
1616 {
1617 fprintf (stderr, "select failed: %s\n", strerror (errno));
1618 break;
1619 }
1620 if (FD_ISSET (STDOUT_FILENO, &wfds))
1621 {
1622 ret =
1623 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1624 write_std.size - write_std.pos);
1625 if (0 > ret)
1626 {
1627 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1628 break;
1629 }
1630 write_std.pos += ret;
1631 if (write_std.pos == write_std.size)
1632 {
1633 write_std.pos = 0;
1634 write_std.size = 0;
1635 }
1636 }
1637 if (FD_ISSET (dev.fd_raw, &wfds))
1638 {
1639 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
1640 if (0 > ret)
1641 {
1642 fprintf (stderr, "Failed to write to WLAN device: %s\n",
1643 strerror (errno));
1644 break;
1645 }
1646 dev.write_pout.pos += ret;
1647 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
1648 {
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);
1652 break;
1653 }
1654 if (dev.write_pout.pos == dev.write_pout.size)
1655 {
1656 dev.write_pout.pos = 0;
1657 dev.write_pout.size = 0;
1658 }
1659 }
1660
1661 if (FD_ISSET (STDIN_FILENO, &rfds))
1662 {
1663 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
1664 if (0 > ret)
1665 {
1666 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1667 break;
1668 }
1669 if (0 == ret)
1670 {
1671 /* stop reading... */
1672 stdin_open = 0;
1673 }
1674 mst_receive (stdin_mst, readbuf, ret);
1675 }
1676
1677 if (FD_ISSET (dev.fd_raw, &rfds))
1678 {
1679 struct GNUNET_MessageHeader *header;
1680 struct Radiotap_rx *rxinfo;
1681 struct ieee80211_frame *datastart;
1682
1683 header = (struct GNUNET_MessageHeader *) write_std.buf;
1684 rxinfo = (struct Radiotap_rx *) &header[1];
1685 datastart = (struct ieee80211_frame *) &rxinfo[1];
1686 ret =
1687 linux_read (&dev, (unsigned char *) datastart,
1688 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
1689 sizeof (struct GNUNET_MessageHeader), rxinfo);
1690 if (0 > ret)
1691 {
1692 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1693 break;
1694 }
1695 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
1696 {
1697 write_std.size =
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);
1702 }
1703 }
1704
1705 }
1706 /* Error handling, try to clean up a bit at least */
1707 mst_destroy (stdin_mst);
1708 close (dev.fd_raw);
1709 return 1; /* we never exit 'normally' */
1710}
1711
1712/* end of gnunet-helper-transport-wlan.c */