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.c2184
1 files changed, 0 insertions, 2184 deletions
diff --git a/src/transport/gnunet-helper-transport-wlan.c b/src/transport/gnunet-helper-transport-wlan.c
deleted file mode 100644
index 72dd8b594..000000000
--- a/src/transport/gnunet-helper-transport-wlan.c
+++ /dev/null
@@ -1,2184 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright Copyright (C) 2009 Thomas d'Otreppe
6
7 GNUnet is free software: you can redistribute it and/or modify it
8 under the terms of the GNU Affero General Public License as published
9 by the Free Software Foundation, either version 3 of the License,
10 or (at your 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 Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 SPDX-License-Identifier: AGPL3.0-or-later
21 */
22/**
23 * @file src/transport/gnunet-helper-transport-wlan.c
24 * @brief mediator between the wlan interface and gnunet; must run as root (SUID will do)
25 * This code will work under GNU/Linux only.
26 * @author David Brodski
27 * @author Christian Grothoff
28 *
29 * This program will allow receiving and sending traffic from the WLAN
30 * interface. It will force traffic to be in 'ad-hoc' mode, use the
31 * proper MAC address of the WLAN interface and use a GNUnet-specific
32 * SSID (and a GNUnet-specific SNAP header). It only takes a single
33 * argument, which is the name of the WLAN interface to use. The
34 * program detects if the interface is not a WLAN interface and exits
35 * with an error in that case.
36 *
37 * Once initialized, the program will first send a 'struct
38 * GNUNET_TRANSPORT_WLAN_HelperControlMessage' to 'stdout'. That
39 * message contains the MAC address of the WLAN interface. It will
40 * then read messages from the WLAN interface and send them together
41 * with performance information as 'struct
42 * GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage' messages to 'stdout'.
43 * Furthermore, it will read a stream of messages from 'stdin' that
44 * have the format from 'struct
45 * GNUNET_TRANSPORT_WLAN_RadiotapSendMessage'. Those messages will
46 * then be sent via the WLAN interface; however, the sender MAC
47 * address will be forced to be the correct address from our WLAN
48 * card. If 'stdin' closes, receiving from the WLAN interface will
49 * continue. If 'stdout' causes a SIGPIPE, the process dies from the
50 * signal. Errors cause an error message to be reported to 'stderr',
51 * in most cases the process also exits (with status code '1'). The
52 * program never terminates normally; it is safe to kill the
53 * process with SIGTERM or SIGKILL at any time.
54 *
55 * Since it uses RAW sockets, the binary must be installed SUID or run
56 * as 'root'. In order to keep the security risk of the resulting
57 * SUID binary minimal, the program ONLY opens the RAW socket with
58 * root privileges, then drops them and only then starts to process
59 * command line arguments. The code also does not link against any
60 * shared libraries (except libc) and is strictly minimal (except for
61 * checking for errors). The following list of people have reviewed
62 * this code and considered it safe since the last modification (if
63 * you reviewed it, please have your name added to the list):
64 *
65 * - Christian Grothoff (Apr 3rd 2012)
66 */
67
68/*-
69 * we use our local copy of ieee80211_radiotap.h
70 *
71 * - since we can't support extensions we don't understand
72 * - since linux does not include it in userspace headers
73 *
74 * Portions of this code were taken from the ieee80211_radiotap.h header,
75 * which is
76 *
77 * Copyright (c) 2003, 2004 David Young. All rights reserved.
78 *
79 * Redistribution and use in source and binary forms, with or without
80 * modification, are permitted provided that the following conditions
81 * are met:
82 * 1. Redistributions of source code must retain the above copyright
83 * notice, this list of conditions and the following disclaimer.
84 * 2. Redistributions in binary form must reproduce the above copyright
85 * notice, this list of conditions and the following disclaimer in the
86 * documentation and/or other materials provided with the distribution.
87 * 3. The name of David Young may not be used to endorse or promote
88 * products derived from this software without specific prior
89 * written permission.
90 *
91 * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
92 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
93 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
94 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
95 * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
96 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
97 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
100 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
102 * OF SUCH DAMAGE.
103 */
104
105/*
106 * Modifications to fit into the linux IEEE 802.11 stack,
107 * Mike Kershaw (dragorn@kismetwireless.net)
108 */
109/*
110 * parts taken from aircrack-ng, parts changend.
111 */
112#include "gnunet_config.h"
113#include <sys/socket.h>
114#include <sys/ioctl.h>
115#include <sys/types.h>
116#include <unistd.h>
117#include <sys/wait.h>
118#include <sys/time.h>
119#include <sys/stat.h>
120#include <netpacket/packet.h>
121#include <linux/if_ether.h>
122#include <linux/if.h>
123#include <linux/wireless.h>
124#include <netinet/in.h>
125#include <linux/if_tun.h>
126#include <stdio.h>
127#include <stdlib.h>
128#include <string.h>
129#include <stdarg.h>
130#include <fcntl.h>
131#include <errno.h>
132#include <dirent.h>
133#include <sys/param.h>
134#include <unistd.h>
135#include <stdint.h>
136
137#include "gnunet_protocols.h"
138#include "plugin_transport_wlan.h"
139
140/**
141 * Packet format type for the messages we receive from
142 * the kernel. This is for Ethernet 10Mbps format (no
143 * performance information included).
144 */
145#define ARPHRD_ETHER 1
146
147
148/**
149 * Packet format type for the messages we receive from
150 * the kernel. This is for plain messages (with no
151 * performance information included).
152 */
153#define ARPHRD_IEEE80211 801
154
155
156/**
157 * Packet format type for the messages we receive from
158 * the kernel. This is for the PRISM format.
159 */
160#define ARPHRD_IEEE80211_PRISM 802
161
162/**
163 * Packet format type for the messages we receive from
164 * the kernel. This is for messages with a
165 * 'struct Ieee80211RadiotapHeader' (see below).
166 */
167#define ARPHRD_IEEE80211_FULL 803
168
169
170/**
171 * Maximum size of a message allowed in either direction
172 * (used for our receive and sent buffers).
173 */
174#define MAXLINE 4096
175
176
177/* ********* structure of messages of type ARPHRD_IEEE80211_PRISM *********** */
178
179/**
180 * Device name length in PRISM frames.
181 * (In the kernel, this is "WLAN_DEVNAMELEN_MAX")
182 */
183#define PRISM_DEVICE_NAME_LENGTH 16
184
185/**
186 * Monitor Frame (indicator that we have a 'struct PrismHeader').
187 */
188#define PRISM_MSGCODE_MONITOR 0x0041
189
190/**
191 * Mac time element. In micro-seconds.
192 * Drivers appear to use a 64bit counter to hold mactime internal
193 * the then fill the prism header with the lower 32 bits
194 */
195#define PRISM_DID_MACTIME 0x2041
196
197/**
198 * Channel element
199 */
200#define PRISM_DID_CHANNEL 0x3041
201
202/**
203 * Signal element. Should be the signal strength in dbm, some people
204 * suggest that instead "100 - (strength in dbm)" is used (to make this
205 * a positive integer).
206 */
207#define PRISM_DID_SIGNAL 0x6041
208
209/**
210 * Noise element
211 */
212#define PRISM_DID_NOISE 0x7041
213
214/**
215 * Rate element, in units/multiples of 500Khz
216 */
217#define PRISM_DID_RATE 0x8041
218
219
220/**
221 * Value is set (supplied)
222 */
223#define PRISM_STATUS_OK 0
224
225/**
226 * Value not supplied.
227 */
228#define PRISM_STATUS_NO_VALUE 1
229
230
231/**
232 * Values in the 'struct PrismHeader'. All in host byte order (!).
233 */
234struct PrismValue
235{
236 /**
237 * This has a different ID for each parameter, see
238 * PRISM_DID_* constants.
239 */
240 uint32_t did;
241
242 /**
243 * See PRISM_STATUS_*-constants. Note that they are unusual: 0 = set; 1 = not set
244 */
245 uint16_t status;
246
247 /**
248 * length of data (which is always a uint32_t, but presumably this can be used
249 * to specify that fewer bytes are used (with values in 'len' from 0-4). We
250 * ignore this field.
251 */
252 uint16_t len;
253
254 /**
255 * The data value
256 */
257 uint32_t data;
258} __attribute__ ((packed));
259
260
261/**
262 * Prism header format ('struct p80211msg' in Linux). All in host byte order (!).
263 */
264struct PrismHeader
265{
266 /**
267 * We expect this to be a PRISM_MSGCODE_*.
268 */
269 uint32_t msgcode;
270
271 /**
272 * The length of the entire header.
273 */
274 uint32_t msglen;
275
276 /**
277 * Name of the device that captured the packet.
278 */
279 char devname[PRISM_DEVICE_NAME_LENGTH];
280
281 /* followed by 'struct PrismValue's. Documentation suggests that these
282 are typically the hosttime, mactime, channel, rssi, sq, signal, noise,
283 rate, istx and frmlen values, but documentation is sparse. So we
284 will use the 'did' fields to find out what we actually got. */
285} __attribute__ ((packed));
286
287
288/* ****** end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */
289
290/* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */
291
292/**
293 * Bits in the 'it_present' bitmask from the 'struct
294 * Ieee80211RadiotapHeader'. For each value, we give the name, data
295 * type, unit and then a description below. Note that the actual size
296 * of the extension can be bigger as arguments must be padded so that
297 * args of a given length must begin at a boundary of that length.
298 * However, note that compound args are allowed (eg, 2 x uint16_t for
299 * IEEE80211_RADIOTAP_CHANNEL) so total argument length is not a
300 * reliable indicator of alignment requirement. See also
301 * 'man 9 ieee80211_radiotap'.
302 */
303enum RadiotapType
304{
305 /**
306 * IEEE80211_RADIOTAP_TSFT __le64 microseconds
307 *
308 * Value in microseconds of the MAC's 64-bit 802.11 Time
309 * Synchronization Function timer when the first bit of the
310 * MPDU arrived at the MAC. For received frames, only.
311 */
312 IEEE80211_RADIOTAP_TSFT = 0,
313
314 /**
315 * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap
316 *
317 * Properties of transmitted and received frames. See flags
318 * defined below.
319 */
320 IEEE80211_RADIOTAP_FLAGS = 1,
321
322 /**
323 * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s
324 *
325 * Tx/Rx data rate
326 */
327 IEEE80211_RADIOTAP_RATE = 2,
328
329 /**
330 * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
331 *
332 * Tx/Rx frequency in MHz, followed by flags (see below).
333 */
334 IEEE80211_RADIOTAP_CHANNEL = 3,
335 /**
336 * IEEE80211_RADIOTAP_FHSS __le16 see below
337 *
338 * For frequency-hopping radios, the hop set (first byte)
339 * and pattern (second byte).
340 */
341 IEEE80211_RADIOTAP_FHSS = 4,
342
343 /**
344 * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
345 * one milliwatt (dBm)
346 *
347 * RF signal power at the antenna, decibel difference from
348 * one milliwatt.
349 */
350 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
351
352 /**
353 * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
354 * one milliwatt (dBm)
355 *
356 * RF noise power at the antenna, decibel difference from one
357 * milliwatt.
358 */
359 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
360
361 /**
362 * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
363 *
364 * Quality of Barker code lock. Unitless. Monotonically
365 * nondecreasing with "better" lock strength. Called "Signal
366 * Quality" in datasheets. (Is there a standard way to measure
367 * this?)
368 */
369 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
370
371 /**
372 * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
373 *
374 * Transmit power expressed as unitless distance from max
375 * power set at factory calibration. 0 is max power.
376 * Monotonically nondecreasing with lower power levels.
377 */
378 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
379
380 /**
381 * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
382 *
383 * Transmit power expressed as decibel distance from max power
384 * set at factory calibration. 0 is max power. Monotonically
385 * nondecreasing with lower power levels.
386 */
387 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
388
389 /**
390 * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
391 * one milliwatt (dBm)
392 *
393 * Transmit power expressed as dBm (decibels from a 1 milliwatt
394 * reference). This is the absolute power level measured at
395 * the antenna port.
396 */
397 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
398
399 /**
400 * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
401 *
402 * Unitless indication of the Rx/Tx antenna for this packet.
403 * The first antenna is antenna 0.
404 */
405 IEEE80211_RADIOTAP_ANTENNA = 11,
406
407 /**
408 * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
409 *
410 * RF signal power at the antenna, decibel difference from an
411 * arbitrary, fixed reference.
412 */
413 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
414
415 /**
416 * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
417 *
418 * RF noise power at the antenna, decibel difference from an
419 * arbitrary, fixed reference point.
420 */
421 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
422
423 /**
424 * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
425 *
426 * Properties of received frames. See flags defined below.
427 */
428 IEEE80211_RADIOTAP_RX_FLAGS = 14,
429
430 /**
431 * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
432 *
433 * Properties of transmitted frames. See flags defined below.
434 */
435 IEEE80211_RADIOTAP_TX_FLAGS = 15,
436
437 /**
438 * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data
439 *
440 * Number of rts retries a transmitted frame used.
441 */
442 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
443
444 /**
445 * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data
446 *
447 * Number of unicast retries a transmitted frame used.
448 */
449 IEEE80211_RADIOTAP_DATA_RETRIES = 17,
450
451 /**
452 * Extension bit, used to indicate that more bits are needed for
453 * the bitmask.
454 */
455 IEEE80211_RADIOTAP_EXT = 31
456};
457
458/**
459 * Bitmask indicating an extension of the bitmask is used.
460 * (Mask corresponding to IEEE80211_RADIOTAP_EXT).
461 */
462#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT)
463
464
465/**
466 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
467 * as part of a 'struct Ieee80211RadiotapHeader' extension
468 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
469 * 'it_present'). The radiotap flags are an 8-bit field.
470 *
471 * Frame was sent/received during CFP (Contention Free Period)
472 */
473#define IEEE80211_RADIOTAP_F_CFP 0x01
474
475/**
476 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
477 * as part of a 'struct Ieee80211RadiotapHeader' extension
478 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
479 * 'it_present'). The radiotap flags are an 8-bit field.
480 *
481 * Frame was sent/received with short preamble
482 */
483#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
484
485/**
486 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
487 * as part of a 'struct Ieee80211RadiotapHeader' extension
488 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
489 * 'it_present'). The radiotap flags are an 8-bit field.
490 *
491 * Frame was sent/received with WEP encryption
492 */
493#define IEEE80211_RADIOTAP_F_WEP 0x04
494
495/**
496 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
497 * as part of a 'struct Ieee80211RadiotapHeader' extension
498 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
499 * 'it_present'). The radiotap flags are an 8-bit field.
500 *
501 * Frame was sent/received with fragmentation
502 */
503#define IEEE80211_RADIOTAP_F_FRAG 0x08
504
505/**
506 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
507 * as part of a 'struct Ieee80211RadiotapHeader' extension
508 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
509 * 'it_present'). The radiotap flags are an 8-bit field.
510 *
511 * Frame includes FCS (CRC at the end that needs to be removeD).
512 */
513#define IEEE80211_RADIOTAP_F_FCS 0x10
514
515/**
516 * Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
517 * as part of a 'struct Ieee80211RadiotapHeader' extension
518 * if the IEEE80211_RADIOTAP_FLAGS bit is set in
519 * 'it_present'). The radiotap flags are an 8-bit field.
520 *
521 * Frame has padding between 802.11 header and payload
522 * (to 32-bit boundary)
523 */
524#define IEEE80211_RADIOTAP_F_DATAPAD 0x20
525
526
527/**
528 * For IEEE80211_RADIOTAP_RX_FLAGS:
529 * frame failed crc check
530 */
531#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
532
533/**
534 * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
535 * failed due to excessive retries
536 */
537#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
538
539/**
540 * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
541 * used cts 'protection'
542 */
543#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
544
545/**
546 * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
547 * used rts/cts handshake
548 */
549#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
550
551/**
552 * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
553 * frame should not be ACKed
554 */
555#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008
556
557/**
558 * For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
559 * sequence number handled by userspace
560 */
561#define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010
562
563
564/**
565 * Generic header for radiotap messages (receiving and sending). A
566 * bit mask (it_present) determines which specific records follow.
567 *
568 * I am trying to describe precisely what the application programmer
569 * should expect in the following, and for that reason I tell the
570 * units and origin of each measurement (where it applies), or else I
571 * use sufficiently weaselly language ("is a monotonically nondecreasing
572 * function of...") that I cannot set false expectations for lawyerly
573 * readers.
574 *
575 * The radio capture header precedes the 802.11 header.
576 * All data in the header is little endian on all platforms.
577 */
578struct Ieee80211RadiotapHeader
579{
580 /**
581 * Version 0. Only increases for drastic changes, introduction of
582 * compatible new fields does not count.
583 */
584 uint8_t it_version;
585
586 /**
587 * Padding. Set to 0.
588 */
589 uint8_t it_pad;
590
591 /**
592 * length of the whole header in bytes, including it_version,
593 * it_pad, it_len, and data fields.
594 */
595 uint16_t it_len;
596
597 /**
598 * A bitmap telling which fields are present. Set bit 31
599 * (0x80000000) to extend the bitmap by another 32 bits. Additional
600 * extensions are made by setting bit 31.
601 */
602 uint32_t it_present;
603};
604
605
606/**
607 * Format of the header we need to prepend to messages to be sent to the
608 * Kernel.
609 */
610struct RadiotapTransmissionHeader
611{
612 /**
613 * First we begin with the 'generic' header we also get when receiving
614 * messages.
615 */
616 struct Ieee80211RadiotapHeader header;
617
618 /**
619 * Transmission rate (we use 0, kernel makes up its mind anyway).
620 */
621 uint8_t rate;
622
623 /**
624 * Padding (we use 0). There is a requirement to pad args, so that
625 * args of a given length must begin at a boundary of that length.
626 * As our next argument is the 'it_len' with 2 bytes, we need 1 byte
627 * of padding.
628 */
629 uint8_t pad1;
630
631 /**
632 * Transmission flags from on the IEEE80211_RADIOTAP_F_TX_* constant family.
633 */
634 uint16_t txflags;
635};
636
637/**
638 * The above 'struct RadiotapTransmissionHeader' should have the
639 * following value for 'header.it_present' based on the presence of
640 * the 'rate' and 'txflags' in the overall struct.
641 */
642#define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 \
643 << \
644 IEEE80211_RADIOTAP_RATE) \
645 | (1 \
646 << \
647 IEEE80211_RADIOTAP_TX_FLAGS))
648
649
650/**
651 * struct Ieee80211RadiotapHeaderIterator - tracks walk through present radiotap arguments
652 * in the radiotap header. Used when we parse radiotap packets received from the kernel.
653 */
654struct Ieee80211RadiotapHeaderIterator
655{
656 /**
657 * pointer to the radiotap header we are walking through
658 */
659 const struct Ieee80211RadiotapHeader *rtheader;
660
661 /**
662 * pointer to current radiotap arg
663 */
664 const uint8_t *this_arg;
665
666 /**
667 * internal next argument pointer
668 */
669 const uint8_t *arg;
670
671 /**
672 * internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT is used).
673 */
674 const uint32_t *next_bitmap;
675
676 /**
677 * length of radiotap header in host byte ordering
678 */
679 size_t max_length;
680
681 /**
682 * internal shifter for current uint32_t bitmap, (it_present in host byte order),
683 * If bit 0 is set, the 'arg_index' argument is present.
684 */
685 uint32_t bitmap_shifter;
686
687 /**
688 * IEEE80211_RADIOTAP_... index of current arg
689 */
690 unsigned int this_arg_index;
691
692 /**
693 * internal next argument index
694 */
695 unsigned int arg_index;
696};
697
698
699/* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
700
701/* ************************** our globals ******************************* */
702
703/**
704 * struct for storing the information of the hardware. There is only
705 * one of these.
706 */
707struct HardwareInfos
708{
709 /**
710 * file descriptor for the raw socket
711 */
712 int fd_raw;
713
714 /**
715 * Which format has the header that we're getting when receiving packets?
716 * Some ARPHRD_IEEE80211_XXX-value.
717 */
718 int arptype_in;
719
720 /**
721 * Name of the interface, not necessarily 0-terminated (!).
722 */
723 char iface[IFNAMSIZ];
724
725 /**
726 * MAC address of our own WLAN interface.
727 */
728 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
729};
730
731
732/**
733 * IO buffer used for buffering data in transit (to wireless or to stdout).
734 */
735struct SendBuffer
736{
737 /**
738 * How many bytes of data are stored in 'buf' for transmission right now?
739 * Data always starts at offset 0 and extends to 'size'.
740 */
741 size_t size;
742
743 /**
744 * How many bytes that were stored in 'buf' did we already write to the
745 * destination? Always smaller than 'size'.
746 */
747 size_t pos;
748
749 /**
750 * Buffered data; twice the maximum allowed message size as we add some
751 * headers.
752 */
753 char buf[MAXLINE * 2];
754};
755
756
757/**
758 * Buffer for data read from stdin to be transmitted to the wirless card.
759 */
760static struct SendBuffer write_pout;
761
762/**
763 * Buffer for data read from the wireless card to be transmitted to stdout.
764 */
765static struct SendBuffer write_std;
766
767
768/* *********** specialized version of server_mst.c begins here ********** */
769
770/**
771 * To what multiple do we align messages? 8 byte should suffice for everyone
772 * for now.
773 */
774#define ALIGN_FACTOR 8
775
776/**
777 * Smallest supported message.
778 */
779#define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
780
781
782/**
783 * Functions with this signature are called whenever a
784 * complete message is received by the tokenizer.
785 *
786 * @param cls closure
787 * @param message the actual message
788 */
789typedef void (*MessageTokenizerCallback) (void *cls,
790 const struct
791 GNUNET_MessageHeader *
792 message);
793
794/**
795 * Handle to a message stream tokenizer.
796 */
797struct MessageStreamTokenizer
798{
799 /**
800 * Function to call on completed messages.
801 */
802 MessageTokenizerCallback cb;
803
804 /**
805 * Closure for cb.
806 */
807 void *cb_cls;
808
809 /**
810 * Size of the buffer (starting at 'hdr').
811 */
812 size_t curr_buf;
813
814 /**
815 * How many bytes in buffer have we already processed?
816 */
817 size_t off;
818
819 /**
820 * How many bytes in buffer are valid right now?
821 */
822 size_t pos;
823
824 /**
825 * Beginning of the buffer. Typed like this to force alignment.
826 */
827 struct GNUNET_MessageHeader *hdr;
828};
829
830
831/**
832 * Create a message stream tokenizer.
833 *
834 * @param cb function to call on completed messages
835 * @param cb_cls closure for cb
836 * @return handle to tokenizer
837 */
838static struct MessageStreamTokenizer *
839mst_create (MessageTokenizerCallback cb,
840 void *cb_cls)
841{
842 struct MessageStreamTokenizer *ret;
843
844 ret = malloc (sizeof(struct MessageStreamTokenizer));
845 if (NULL == ret)
846 {
847 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
848 exit (1);
849 }
850 ret->hdr = malloc (MIN_BUFFER_SIZE);
851 if (NULL == ret->hdr)
852 {
853 fprintf (stderr, "Failed to allocate buffer for alignment\n");
854 exit (1);
855 }
856 ret->curr_buf = MIN_BUFFER_SIZE;
857 ret->cb = cb;
858 ret->cb_cls = cb_cls;
859 return ret;
860}
861
862
863/**
864 * Add incoming data to the receive buffer and call the
865 * callback for all complete messages.
866 *
867 * @param mst tokenizer to use
868 * @param buf input data to add
869 * @param size number of bytes in buf
870 * @return GNUNET_OK if we are done processing (need more data)
871 * GNUNET_SYSERR if the data stream is corrupt
872 */
873static int
874mst_receive (struct MessageStreamTokenizer *mst,
875 const char *buf, size_t size)
876{
877 const struct GNUNET_MessageHeader *hdr;
878 size_t delta;
879 uint16_t want;
880 char *ibuf;
881 int need_align;
882 unsigned long offset;
883 int ret;
884
885 ret = GNUNET_OK;
886 ibuf = (char *) mst->hdr;
887 while (mst->pos > 0)
888 {
889do_align:
890 if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
891 (0 != (mst->off % ALIGN_FACTOR)))
892 {
893 /* need to align or need more space */
894 mst->pos -= mst->off;
895 memmove (ibuf, &ibuf[mst->off], mst->pos);
896 mst->off = 0;
897 }
898 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
899 {
900 delta =
901 GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
902 - (mst->pos - mst->off), size);
903 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
904 mst->pos += delta;
905 buf += delta;
906 size -= delta;
907 }
908 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
909 {
910 return GNUNET_OK;
911 }
912 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
913 want = ntohs (hdr->size);
914 if (want < sizeof(struct GNUNET_MessageHeader))
915 {
916 fprintf (stderr,
917 "Received invalid message from stdin\n");
918 exit (1);
919 }
920 if (mst->curr_buf - mst->off < want)
921 {
922 /* need more space */
923 mst->pos -= mst->off;
924 memmove (ibuf, &ibuf[mst->off], mst->pos);
925 mst->off = 0;
926 }
927 if (want > mst->curr_buf)
928 {
929 mst->hdr = realloc (mst->hdr, want);
930 if (NULL == mst->hdr)
931 {
932 fprintf (stderr, "Failed to allocate buffer for alignment\n");
933 exit (1);
934 }
935 ibuf = (char *) mst->hdr;
936 mst->curr_buf = want;
937 }
938 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
939 if (mst->pos - mst->off < want)
940 {
941 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
942 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
943 mst->pos += delta;
944 buf += delta;
945 size -= delta;
946 }
947 if (mst->pos - mst->off < want)
948 {
949 return GNUNET_OK;
950 }
951 mst->cb (mst->cb_cls, hdr);
952 mst->off += want;
953 if (mst->off == mst->pos)
954 {
955 /* reset to beginning of buffer, it's free right now! */
956 mst->off = 0;
957 mst->pos = 0;
958 }
959 }
960 while (size > 0)
961 {
962 if (size < sizeof(struct GNUNET_MessageHeader))
963 break;
964 offset = (unsigned long) buf;
965 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
966 if (GNUNET_NO == need_align)
967 {
968 /* can try to do zero-copy and process directly from original buffer */
969 hdr = (const struct GNUNET_MessageHeader *) buf;
970 want = ntohs (hdr->size);
971 if (want < sizeof(struct GNUNET_MessageHeader))
972 {
973 fprintf (stderr,
974 "Received invalid message from stdin\n");
975 exit (1);
976 }
977 if (size < want)
978 break; /* or not, buffer incomplete, so copy to private buffer... */
979 mst->cb (mst->cb_cls, hdr);
980 buf += want;
981 size -= want;
982 }
983 else
984 {
985 /* need to copy to private buffer to align;
986 * yes, we go a bit more spaghetti than usual here */
987 goto do_align;
988 }
989 }
990 if (size > 0)
991 {
992 if (size + mst->pos > mst->curr_buf)
993 {
994 mst->hdr = realloc (mst->hdr, size + mst->pos);
995 if (NULL == mst->hdr)
996 {
997 fprintf (stderr, "Failed to allocate buffer for alignment\n");
998 exit (1);
999 }
1000 ibuf = (char *) mst->hdr;
1001 mst->curr_buf = size + mst->pos;
1002 }
1003 if (mst->pos + size > mst->curr_buf)
1004 {
1005 fprintf (stderr,
1006 "Assertion failed\n");
1007 exit (1);
1008 }
1009 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
1010 mst->pos += size;
1011 }
1012 return ret;
1013}
1014
1015
1016/**
1017 * Destroys a tokenizer.
1018 *
1019 * @param mst tokenizer to destroy
1020 */
1021static void
1022mst_destroy (struct MessageStreamTokenizer *mst)
1023{
1024 free (mst->hdr);
1025 free (mst);
1026}
1027
1028
1029/* ***************** end of server_mst.c clone ***************** **/
1030
1031
1032/* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */
1033
1034/**
1035 * Radiotap header iteration
1036 *
1037 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
1038 * struct Ieee80211RadiotapHeaderIterator (no need to init the struct beforehand)
1039 * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1
1040 * if there are no more args in the header, or the next argument type index
1041 * that is present. The iterator's this_arg member points to the start of the
1042 * argument associated with the current argument index that is present,
1043 * which can be found in the iterator's this_arg_index member. This arg
1044 * index corresponds to the IEEE80211_RADIOTAP_... defines.
1045 *
1046 * @param iterator iterator to initialize
1047 * @param radiotap_header message to parse
1048 * @param max_length number of valid bytes in radiotap_header
1049 * @return 0 on success, -1 on error
1050 */
1051static int
1052ieee80211_radiotap_iterator_init (struct
1053 Ieee80211RadiotapHeaderIterator *iterator,
1054 const struct
1055 Ieee80211RadiotapHeader *radiotap_header,
1056 size_t max_length)
1057{
1058 if ((iterator == NULL) ||
1059 (radiotap_header == NULL))
1060 return -1;
1061
1062 /* Linux only supports version 0 radiotap format */
1063 if (0 != radiotap_header->it_version)
1064 return -1;
1065
1066 /* sanity check for allowed length and radiotap length field */
1067 if ((max_length < sizeof(struct Ieee80211RadiotapHeader)) ||
1068 (max_length < (GNUNET_le16toh (radiotap_header->it_len))))
1069 return -1;
1070
1071 memset (iterator, 0, sizeof(struct Ieee80211RadiotapHeaderIterator));
1072 iterator->rtheader = radiotap_header;
1073 iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
1074 iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
1075 iterator->arg = ((uint8_t *) radiotap_header) + sizeof(struct
1076 Ieee80211RadiotapHeader);
1077
1078 /* find payload start allowing for extended bitmap(s) */
1079 if (0 != (iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
1080 {
1081 while (GNUNET_le32toh (*((uint32_t *) iterator->arg))
1082 & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
1083 {
1084 iterator->arg += sizeof(uint32_t);
1085 /*
1086 * check for insanity where the present bitmaps
1087 * keep claiming to extend up to or even beyond the
1088 * stated radiotap header length
1089 */if (iterator->arg - ((uint8_t *) iterator->rtheader) >
1090 iterator->max_length)
1091 return -1;
1092 }
1093 iterator->arg += sizeof(uint32_t);
1094 /*
1095 * no need to check again for blowing past stated radiotap
1096 * header length, because ieee80211_radiotap_iterator_next
1097 * checks it before it is dereferenced
1098 */}
1099 /* we are all initialized happily */
1100 return 0;
1101}
1102
1103
1104/**
1105 * Returns the next radiotap parser iterator arg.
1106 *
1107 * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...)
1108 * and sets iterator->this_arg to point to the payload for the arg. It takes
1109 * care of alignment handling and extended present fields. interator->this_arg
1110 * can be changed by the caller. The args pointed to are in little-endian
1111 * format.
1112 *
1113 * @param iterator: radiotap_iterator to move to next arg (if any)
1114 * @return next present arg index on success or -1 if no more or error
1115 */
1116static int
1117ieee80211_radiotap_iterator_next (struct
1118 Ieee80211RadiotapHeaderIterator *iterator)
1119{
1120 /*
1121 * small length lookup table for all radiotap types we heard of
1122 * starting from b0 in the bitmap, so we can walk the payload
1123 * area of the radiotap header
1124 *
1125 * There is a requirement to pad args, so that args
1126 * of a given length must begin at a boundary of that length
1127 * -- but note that compound args are allowed (eg, 2 x uint16_t
1128 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
1129 * a reliable indicator of alignment requirement.
1130 *
1131 * upper nybble: content alignment for arg
1132 * lower nybble: content length for arg
1133 */static const uint8_t rt_sizes[] = {
1134 [IEEE80211_RADIOTAP_TSFT] = 0x88,
1135 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
1136 [IEEE80211_RADIOTAP_RATE] = 0x11,
1137 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
1138 [IEEE80211_RADIOTAP_FHSS] = 0x22,
1139 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
1140 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
1141 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
1142 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
1143 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
1144 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
1145 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
1146 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
1147 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
1148 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
1149 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
1150 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
1151 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
1152 /*
1153 * add more here as they are defined in
1154 * include/net/ieee80211_radiotap.h
1155 */
1156 };
1157
1158 /*
1159 * for every radiotap entry we can at
1160 * least skip (by knowing the length)...
1161 */
1162 while (iterator->arg_index < sizeof(rt_sizes))
1163 {
1164 int hit = (0 != (iterator->bitmap_shifter & 1));
1165
1166 if (hit)
1167 {
1168 unsigned int wanted_alignment;
1169 unsigned int unalignment;
1170 /*
1171 * arg is present, account for alignment padding
1172 * 8-bit args can be at any alignment
1173 * 16-bit args must start on 16-bit boundary
1174 * 32-bit args must start on 32-bit boundary
1175 * 64-bit args must start on 64-bit boundary
1176 *
1177 * note that total arg size can differ from alignment of
1178 * elements inside arg, so we use upper nybble of length table
1179 * to base alignment on. First, 'wanted_alignment' is set to be
1180 * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit
1181 * arguments. Then, we calculate the 'unalignment' (how many
1182 * bytes we are over by taking the difference of 'arg' and the
1183 * overall starting point modulo the desired alignment. As
1184 * desired alignments are powers of two, we can do modulo with
1185 * binary "&" (and also avoid the possibility of a division by
1186 * zero if the 'rt_sizes' table contains bogus entries).
1187 *
1188 * also note: these alignments are relative to the start of the
1189 * radiotap header. There is no guarantee that the radiotap
1190 * header itself is aligned on any kind of boundary, thus we
1191 * need to really look at the delta here.
1192 */wanted_alignment = rt_sizes[iterator->arg_index] >> 4;
1193 unalignment = (((void *) iterator->arg) - ((void *) iterator->rtheader))
1194 & (wanted_alignment - 1);
1195 if (0 != unalignment)
1196 {
1197 /* need padding (by 'wanted_alignment - unalignment') */
1198 iterator->arg_index += wanted_alignment - unalignment;
1199 }
1200
1201 /*
1202 * this is what we will return to user, but we need to
1203 * move on first so next call has something fresh to test
1204 */
1205 iterator->this_arg_index = iterator->arg_index;
1206 iterator->this_arg = iterator->arg;
1207
1208 /* internally move on the size of this arg (using lower nybble from
1209 the table) */
1210 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
1211
1212 /*
1213 * check for insanity where we are given a bitmap that
1214 * claims to have more arg content than the length of the
1215 * radiotap section. We will normally end up equalling this
1216 * max_length on the last arg, never exceeding it.
1217 */if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
1218 iterator->max_length)
1219 return -1;
1220 }
1221
1222 /* Now, move on to next bit / next entry */
1223 iterator->arg_index++;
1224
1225 if (0 == (iterator->arg_index % 32))
1226 {
1227 /* completed current uint32_t bitmap */
1228 if (0 != (iterator->bitmap_shifter & 1))
1229 {
1230 /* bit 31 was set, there is more; move to next uint32_t bitmap */
1231 iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
1232 iterator->next_bitmap++;
1233 }
1234 else
1235 {
1236 /* no more bitmaps: end (by setting arg_index to high, unsupported value) */
1237 iterator->arg_index = sizeof(rt_sizes);
1238 }
1239 }
1240 else
1241 {
1242 /* just try the next bit (while loop will move on) */
1243 iterator->bitmap_shifter >>= 1;
1244 }
1245
1246 /* if we found a valid arg earlier, return it now */
1247 if (hit)
1248 return iterator->this_arg_index;
1249 }
1250
1251 /* we don't know how to handle any more args (or there are no more),
1252 so we're done (this is not an error) */
1253 return -1;
1254}
1255
1256
1257/**
1258 * Calculate crc32, the start of the calculation
1259 *
1260 * @param buf buffer to calc the crc
1261 * @param len len of the buffer
1262 * @return crc sum
1263 */
1264static unsigned long
1265calc_crc_osdep (const unsigned char *buf, size_t len)
1266{
1267 static const unsigned long int crc_tbl_osdep[256] = {
1268 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1269 0xE963A535, 0x9E6495A3,
1270 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
1271 0xE7B82D07, 0x90BF1D91,
1272 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
1273 0xF4D4B551, 0x83D385C7,
1274 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1275 0xFA0F3D63, 0x8D080DF5,
1276 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
1277 0xD20D85FD, 0xA50AB56B,
1278 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
1279 0xDCD60DCF, 0xABD13D59,
1280 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1281 0xCFBA9599, 0xB8BDA50F,
1282 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
1283 0xC1611DAB, 0xB6662D3D,
1284 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
1285 0x9FBFE4A5, 0xE8B8D433,
1286 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1287 0x91646C97, 0xE6635C01,
1288 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
1289 0x8208F4C1, 0xF50FC457,
1290 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
1291 0x8CD37CF3, 0xFBD44C65,
1292 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1293 0xA4D1C46D, 0xD3D6F4FB,
1294 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
1295 0xAA0A4C5F, 0xDD0D7CC9,
1296 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
1297 0xB966D409, 0xCE61E49F,
1298 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1299 0xB7BD5C3B, 0xC0BA6CAD,
1300 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1301 0x04DB2615, 0x73DC1683,
1302 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1303 0x0A00AE27, 0x7D079EB1,
1304 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1305 0x196C3671, 0x6E6B06E7,
1306 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1307 0x17B7BE43, 0x60B08ED5,
1308 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1309 0x3FB506DD, 0x48B2364B,
1310 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1311 0x316E8EEF, 0x4669BE79,
1312 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1313 0x220216B9, 0x5505262F,
1314 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1315 0x2CD99E8B, 0x5BDEAE1D,
1316 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1317 0x72076785, 0x05005713,
1318 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1319 0x7CDCEFB7, 0x0BDBDF21,
1320 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1321 0x6FB077E1, 0x18B74777,
1322 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1323 0x616BFFD3, 0x166CCF45,
1324 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1325 0x4969474D, 0x3E6E77DB,
1326 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1327 0x47B2CF7F, 0x30B5FFE9,
1328 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1329 0x54DE5729, 0x23D967BF,
1330 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1331 0x5A05DF1B, 0x2D02EF8D
1332 };
1333
1334 unsigned long crc = 0xFFFFFFFF;
1335
1336 for (; len > 0; len--, buf++)
1337 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1338 return(~crc);
1339}
1340
1341
1342/**
1343 * Calculate and check crc of the wlan packet
1344 *
1345 * @param buf buffer of the packet, with len + 4 bytes of data,
1346 * the last 4 bytes being the checksum
1347 * @param len length of the payload in data
1348 * @return 0 on success (checksum matches), 1 on error
1349 */
1350static int
1351check_crc_buf_osdep (const unsigned char *buf, size_t len)
1352{
1353 unsigned long crc;
1354
1355 crc = calc_crc_osdep (buf, len);
1356 buf += len;
1357 if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
1358 ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
1359 return 0;
1360 return 1;
1361}
1362
1363
1364/* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */
1365
1366
1367/* ************beginning of code for reading packets from kernel ************** */
1368
1369/**
1370 * Return the channel from the frequency (in Mhz)
1371 *
1372 * @param frequency of the channel
1373 * @return number of the channel
1374 */
1375static int
1376get_channel_from_frequency (int32_t frequency)
1377{
1378 if ((frequency >= 2412) && (frequency <= 2472))
1379 return (frequency - 2407) / 5;
1380 if (frequency == 2484)
1381 return 14;
1382 if ((frequency >= 5000) && (frequency <= 6100))
1383 return (frequency - 5000) / 5;
1384 return -1;
1385}
1386
1387
1388/**
1389 * Get the channel used by our WLAN interface.
1390 *
1391 * @param dev pointer to the dev struct of the card
1392 * @return channel number, -1 on error
1393 */
1394static int
1395linux_get_channel (const struct HardwareInfos *dev)
1396{
1397 struct iwreq wrq;
1398 int32_t frequency;
1399
1400 memset (&wrq, 0, sizeof(struct iwreq));
1401 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1402 if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq))
1403 return -1;
1404 frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */
1405 if (100000000 < frequency)
1406 frequency /= 100000;
1407 else if (1000000 < frequency)
1408 frequency /= 1000;
1409 if (1000 < frequency)
1410 return get_channel_from_frequency (frequency);
1411 return frequency;
1412}
1413
1414
1415/**
1416 * Read from the raw socket (the wlan card), parse the packet and
1417 * put the result into the buffer for transmission to 'stdout'.
1418 *
1419 * @param dev pointer to the struct of the wlan card
1420 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1421 * followed by the actual payload
1422 * @param buf_size size of the buffer
1423 * @param ri where to write radiotap_rx info
1424 * @return number of bytes written to 'buf'
1425 */
1426static ssize_t
1427linux_read (struct HardwareInfos *dev,
1428 unsigned char *buf, size_t buf_size,
1429 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1430{
1431 unsigned char tmpbuf[buf_size];
1432 ssize_t caplen;
1433 size_t n;
1434 int got_signal = 0;
1435 int got_noise = 0;
1436 int got_channel = 0;
1437 int fcs_removed = 0;
1438
1439 caplen = read (dev->fd_raw, tmpbuf, buf_size);
1440 if (0 > caplen)
1441 {
1442 if (EAGAIN == errno)
1443 return 0;
1444 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1445 return -1;
1446 }
1447
1448 memset (ri, 0, sizeof(*ri));
1449 switch (dev->arptype_in)
1450 {
1451 case ARPHRD_IEEE80211_PRISM:
1452 {
1453 const struct PrismHeader *ph;
1454
1455 ph = (const struct PrismHeader*) tmpbuf;
1456 n = ph->msglen;
1457 if ((n < 8) || (n >= caplen))
1458 return 0; /* invalid format */
1459 if ((PRISM_MSGCODE_MONITOR == ph->msgcode) &&
1460 (n >= sizeof(struct PrismHeader)))
1461 {
1462 const char *pos;
1463 size_t left;
1464 struct PrismValue pv;
1465
1466 left = n - sizeof(struct PrismHeader);
1467 pos = (const char *) &ph[1];
1468 while (left > sizeof(struct PrismValue))
1469 {
1470 left -= sizeof(struct PrismValue);
1471 GNUNET_memcpy (&pv, pos, sizeof(struct PrismValue));
1472 pos += sizeof(struct PrismValue);
1473
1474 switch (pv.did)
1475 {
1476 case PRISM_DID_NOISE:
1477 if (PRISM_STATUS_OK == pv.status)
1478 {
1479 ri->ri_noise = pv.data;
1480 /* got_noise = 1; */
1481 }
1482 break;
1483
1484 case PRISM_DID_RATE:
1485 if (PRISM_STATUS_OK == pv.status)
1486 ri->ri_rate = pv.data * 500000;
1487 break;
1488
1489 case PRISM_DID_CHANNEL:
1490 if (PRISM_STATUS_OK == pv.status)
1491 {
1492 ri->ri_channel = pv.data;
1493 got_channel = 1;
1494 }
1495 break;
1496
1497 case PRISM_DID_MACTIME:
1498 if (PRISM_STATUS_OK == pv.status)
1499 ri->ri_mactime = pv.data;
1500 break;
1501
1502 case PRISM_DID_SIGNAL:
1503 if (PRISM_STATUS_OK == pv.status)
1504 {
1505 ri->ri_power = pv.data;
1506 /* got_signal = 1; */
1507 }
1508 break;
1509 }
1510 }
1511 }
1512 if ((n < 8) || (n >= caplen))
1513 return 0; /* invalid format */
1514 }
1515 break;
1516
1517 case ARPHRD_IEEE80211_FULL:
1518 {
1519 struct Ieee80211RadiotapHeaderIterator iterator;
1520 struct Ieee80211RadiotapHeader *rthdr;
1521
1522 memset (&iterator, 0, sizeof(iterator));
1523 rthdr = (struct Ieee80211RadiotapHeader *) tmpbuf;
1524 n = GNUNET_le16toh (rthdr->it_len);
1525 if ((n < sizeof(struct Ieee80211RadiotapHeader)) || (n >= caplen))
1526 return 0; /* invalid 'it_len' */
1527 if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
1528 return 0;
1529 /* go through the radiotap arguments we have been given by the driver */
1530 while (0 <= ieee80211_radiotap_iterator_next (&iterator))
1531 {
1532 switch (iterator.this_arg_index)
1533 {
1534 case IEEE80211_RADIOTAP_TSFT:
1535 ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1536 break;
1537
1538 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1539 if (! got_signal)
1540 {
1541 ri->ri_power = *((int8_t *) iterator.this_arg);
1542 got_signal = 1;
1543 }
1544 break;
1545
1546 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1547 if (! got_signal)
1548 {
1549 ri->ri_power = *((int8_t *) iterator.this_arg);
1550 got_signal = 1;
1551 }
1552 break;
1553
1554 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1555 if (! got_noise)
1556 {
1557 ri->ri_noise = *((int8_t *) iterator.this_arg);
1558 got_noise = 1;
1559 }
1560 break;
1561
1562 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1563 if (! got_noise)
1564 {
1565 ri->ri_noise = *((int8_t *) iterator.this_arg);
1566 got_noise = 1;
1567 }
1568 break;
1569
1570 case IEEE80211_RADIOTAP_ANTENNA:
1571 ri->ri_antenna = *iterator.this_arg;
1572 break;
1573
1574 case IEEE80211_RADIOTAP_CHANNEL:
1575 ri->ri_channel = *iterator.this_arg;
1576 got_channel = 1;
1577 break;
1578
1579 case IEEE80211_RADIOTAP_RATE:
1580 ri->ri_rate = (*iterator.this_arg) * 500000;
1581 break;
1582
1583 case IEEE80211_RADIOTAP_FLAGS:
1584 {
1585 uint8_t flags = *iterator.this_arg;
1586 /* is the CRC visible at the end? if so, remove */
1587 if (0 != (flags & IEEE80211_RADIOTAP_F_FCS))
1588 {
1589 fcs_removed = 1;
1590 caplen -= sizeof(uint32_t);
1591 }
1592 break;
1593 }
1594
1595 case IEEE80211_RADIOTAP_RX_FLAGS:
1596 {
1597 uint16_t flags = ntohs (*((uint16_t *) iterator.this_arg));
1598 if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS))
1599 return 0;
1600 }
1601 break;
1602 } /* end of 'switch' */
1603 } /* end of the 'while' loop */
1604 }
1605 break;
1606
1607 case ARPHRD_IEEE80211:
1608 n = 0; /* no header */
1609 break;
1610
1611 case ARPHRD_ETHER:
1612 {
1613 if (sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
1614 return 0; /* invalid */
1615 GNUNET_memcpy (&buf[sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)],
1616 tmpbuf + sizeof(struct
1617 GNUNET_TRANSPORT_WLAN_Ieee8023Frame),
1618 caplen - sizeof(struct
1619 GNUNET_TRANSPORT_WLAN_Ieee8023Frame)
1620 - 4 /* 4 byte FCS */);
1621 return caplen - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
1622 }
1623
1624 default:
1625 errno = ENOTSUP; /* unsupported format */
1626 return -1;
1627 }
1628 caplen -= n;
1629 if (! got_channel)
1630 ri->ri_channel = linux_get_channel (dev);
1631
1632 /* detect CRC32 at the end, even if the flag wasn't set and remove it */
1633 if ((0 == fcs_removed) &&
1634 (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof(uint32_t))))
1635 {
1636 /* NOTE: this heuristic can of course fail if there happens to
1637 be a matching checksum at the end. Would be good to have
1638 some data to see how often this heuristic actually works. */
1639 caplen -= sizeof(uint32_t);
1640 }
1641 /* copy payload to target buffer */
1642 GNUNET_memcpy (buf, tmpbuf + n, caplen);
1643 return caplen;
1644}
1645
1646
1647/* ************end of code for reading packets from kernel ************** */
1648
1649/* ************other helper functions for main start here ************** */
1650
1651
1652/**
1653 * Open the wireless network interface for reading/writing.
1654 *
1655 * @param dev pointer to the device struct
1656 * @return 0 on success
1657 */
1658static int
1659open_device_raw (struct HardwareInfos *dev)
1660{
1661 struct ifreq ifr;
1662 struct iwreq wrq;
1663 struct packet_mreq mr;
1664 struct sockaddr_ll sll;
1665
1666 /* find the interface index */
1667 memset (&ifr, 0, sizeof(ifr));
1668 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1669 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1670 {
1671 fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1672 IFNAMSIZ, dev->iface, strerror (errno));
1673 return 1;
1674 }
1675
1676 /* lookup the hardware type */
1677 memset (&sll, 0, sizeof(sll));
1678 sll.sll_family = AF_PACKET;
1679 sll.sll_ifindex = ifr.ifr_ifindex;
1680 sll.sll_protocol = htons (ETH_P_ALL);
1681 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1682 {
1683 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1684 IFNAMSIZ, dev->iface, strerror (errno));
1685 return 1;
1686 }
1687 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1688 (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1689 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1690 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)))
1691 {
1692 fprintf (stderr,
1693 "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
1694 IFNAMSIZ, dev->iface,
1695 ifr.ifr_hwaddr.sa_family);
1696 return 1;
1697 }
1698
1699 /* lookup iw mode */
1700 memset (&wrq, 0, sizeof(struct iwreq));
1701 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1702 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1703 {
1704 /* most probably not supported (ie for rtap ipw interface) *
1705 * so just assume its correctly set... */
1706 wrq.u.mode = IW_MODE_MONITOR;
1707 }
1708
1709 if ((wrq.u.mode != IW_MODE_MONITOR) &&
1710 (wrq.u.mode != IW_MODE_ADHOC))
1711 {
1712 fprintf (stderr,
1713 "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
1714 IFNAMSIZ, dev->iface,
1715 wrq.u.mode);
1716 return 1;
1717 }
1718
1719 /* Is interface st to up, broadcast & running ? */
1720 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1721 {
1722 /* Bring interface up */
1723 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1724
1725 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1726 {
1727 fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1728 IFNAMSIZ, dev->iface, strerror (errno));
1729 return 1;
1730 }
1731 }
1732
1733 /* bind the raw socket to the interface */
1734 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof(sll)))
1735 {
1736 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1737 dev->iface, strerror (errno));
1738 return 1;
1739 }
1740
1741 /* lookup the hardware type */
1742 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1743 {
1744 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1745 IFNAMSIZ, dev->iface, strerror (errno));
1746 return 1;
1747 }
1748
1749 GNUNET_memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1750 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1751 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1752 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1753 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1754 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1755 {
1756 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1757 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1758 return 1;
1759 }
1760
1761 /* enable promiscuous mode */
1762 memset (&mr, 0, sizeof(mr));
1763 mr.mr_ifindex = sll.sll_ifindex;
1764 mr.mr_type = PACKET_MR_PROMISC;
1765 if (0 !=
1766 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1767 sizeof(mr)))
1768 {
1769 fprintf (stderr,
1770 "Failed to enable promiscuous mode on interface `%.*s'\n",
1771 IFNAMSIZ,
1772 dev->iface);
1773 return 1;
1774 }
1775 return 0;
1776}
1777
1778
1779/**
1780 * Test if the given interface name really corresponds to a wireless
1781 * device.
1782 *
1783 * @param iface name of the interface
1784 * @return 0 on success, 1 on error
1785 */
1786static int
1787test_wlan_interface (const char *iface)
1788{
1789 char strbuf[512];
1790 struct stat sbuf;
1791 int ret;
1792
1793 ret = snprintf (strbuf, sizeof(strbuf),
1794 "/sys/class/net/%s/phy80211/subsystem",
1795 iface);
1796 if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1797 {
1798 fprintf (stderr,
1799 "Did not find 802.11 interface `%s'. Exiting.\n",
1800 iface);
1801 exit (1);
1802 }
1803 return 0;
1804}
1805
1806
1807/**
1808 * Test incoming packets mac for being our own.
1809 *
1810 * @param taIeeeHeader buffer of the packet
1811 * @param dev the Hardware_Infos struct
1812 * @return 0 if mac belongs to us, 1 if mac is for another target
1813 */
1814static int
1815mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1816 const struct HardwareInfos *dev)
1817{
1818 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1819
1820 if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1821 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1822 return 0; /* some drivers set no Macs, then assume it is all for us! */
1823
1824 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1825 return 1; /* not a GNUnet ad-hoc package */
1826 if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1827 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1828 return 0; /* for us, or broadcast */
1829 return 1; /* not for us */
1830}
1831
1832
1833/**
1834 * Set the wlan header to sane values to make attacks more difficult
1835 *
1836 * @param taIeeeHeader pointer to the header of the packet
1837 * @param dev pointer to the Hardware_Infos struct
1838 */
1839static void
1840mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1841 const struct HardwareInfos *dev)
1842{
1843 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1844 taIeeeHeader->addr2 = dev->pl_mac;
1845 taIeeeHeader->addr3 = mac_bssid_gnunet;
1846}
1847
1848
1849/**
1850 * Process data from the stdin. Takes the message, prepends the
1851 * radiotap transmission header, forces the sender MAC to be correct
1852 * and puts it into our buffer for transmission to the kernel.
1853 *
1854 * @param cls pointer to the device struct ('struct HardwareInfos*')
1855 * @param hdr pointer to the start of the packet
1856 */
1857static void
1858stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1859{
1860 struct HardwareInfos *dev = cls;
1861 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1862 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
1863 size_t sendsize;
1864 struct RadiotapTransmissionHeader rtheader;
1865 struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
1866
1867 sendsize = ntohs (hdr->size);
1868 if ((sendsize <
1869 sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1870 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)))
1871 {
1872 fprintf (stderr, "Received malformed message\n");
1873 exit (1);
1874 }
1875 sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1876 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1877 if (MAXLINE < sendsize)
1878 {
1879 fprintf (stderr, "Packet too big for buffer\n");
1880 exit (1);
1881 }
1882 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1883 switch (dev->arptype_in)
1884 {
1885 case ARPHRD_IEEE80211_PRISM:
1886 case ARPHRD_IEEE80211_FULL:
1887 case ARPHRD_IEEE80211:
1888 rtheader.header.it_version = 0;
1889 rtheader.header.it_pad = 0;
1890 rtheader.header.it_len = GNUNET_htole16 (sizeof(rtheader));
1891 rtheader.header.it_present = GNUNET_htole16 (
1892 IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK);
1893 rtheader.rate = header->rate;
1894 rtheader.pad1 = 0;
1895 rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK
1896 | IEEE80211_RADIOTAP_F_TX_NOSEQ);
1897 GNUNET_memcpy (write_pout.buf, &rtheader, sizeof(rtheader));
1898 GNUNET_memcpy (&write_pout.buf[sizeof(rtheader)], &header->frame, sendsize);
1899 wlanheader = (struct
1900 GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof(
1901 rtheader)
1902 ];
1903
1904 /* payload contains MAC address, but we don't trust it, so we'll
1905 * overwrite it with OUR MAC address to prevent mischief */
1906 mac_set (wlanheader, dev);
1907 write_pout.size = sendsize + sizeof(rtheader);
1908 break;
1909
1910 case ARPHRD_ETHER:
1911 etheader.dst = header->frame.addr1;
1912 /* etheader.src = header->frame.addr2; --- untrusted input */
1913 etheader.src = dev->pl_mac;
1914 etheader.type = htons (ETH_P_IP);
1915 GNUNET_memcpy (write_pout.buf, &etheader, sizeof(etheader));
1916 GNUNET_memcpy (&write_pout.buf[sizeof(etheader)], &header[1], sendsize
1917 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1918 write_pout.size = sendsize - sizeof(struct
1919 GNUNET_TRANSPORT_WLAN_Ieee80211Frame)
1920 + sizeof(etheader);
1921 break;
1922
1923 default:
1924 fprintf (stderr,
1925 "Unsupported ARPTYPE!\n");
1926 break;
1927 }
1928}
1929
1930
1931/**
1932 * Main function of the helper. This code accesses a WLAN interface
1933 * in monitoring mode (layer 2) and then forwards traffic in both
1934 * directions between the WLAN interface and stdin/stdout of this
1935 * process. Error messages are written to stdout.
1936 *
1937 * @param argc number of arguments, must be 2
1938 * @param argv arguments only argument is the name of the interface (e.g. 'mon0')
1939 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1940 */
1941int
1942main (int argc, char *argv[])
1943{
1944 struct HardwareInfos dev;
1945 char readbuf[MAXLINE];
1946 int maxfd;
1947 fd_set rfds;
1948 fd_set wfds;
1949 int stdin_open;
1950 struct MessageStreamTokenizer *stdin_mst;
1951 int raw_eno;
1952
1953 /* assert privs so we can modify the firewall rules! */
1954 {
1955#ifdef HAVE_SETRESUID
1956 uid_t uid = getuid ();
1957
1958 if (0 != setresuid (uid, 0, 0))
1959 {
1960 fprintf (stderr,
1961 "Failed to setresuid to root: %s\n",
1962 strerror (errno));
1963 return 254;
1964 }
1965#else
1966 if (0 != seteuid (0))
1967 {
1968 fprintf (stderr,
1969 "Failed to seteuid back to root: %s\n", strerror (errno));
1970 return 254;
1971 }
1972#endif
1973 }
1974
1975 /* make use of SGID capabilities on POSIX */
1976 memset (&dev, 0, sizeof(dev));
1977 dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1978 raw_eno = errno; /* remember for later */
1979
1980 /* now that we've dropped root rights, we can do error checking */
1981 if (2 != argc)
1982 {
1983 fprintf (stderr,
1984 "You must specify the name of the interface as the first and only argument to this program.\n");
1985 if (-1 != dev.fd_raw)
1986 (void) close (dev.fd_raw);
1987 return 1;
1988 }
1989
1990 if (-1 == dev.fd_raw)
1991 {
1992 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1993 return 1;
1994 }
1995 if (dev.fd_raw >= FD_SETSIZE)
1996 {
1997 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1998 dev.fd_raw, FD_SETSIZE);
1999 (void) close (dev.fd_raw);
2000 return 1;
2001 }
2002 if (0 != test_wlan_interface (argv[1]))
2003 {
2004 (void) close (dev.fd_raw);
2005 return 1;
2006 }
2007 memcpy (dev.iface, argv[1], IFNAMSIZ);
2008 if (0 != open_device_raw (&dev))
2009 {
2010 (void) close (dev.fd_raw);
2011 return 1;
2012 }
2013
2014 /* drop privs */
2015 {
2016 uid_t uid = getuid ();
2017#ifdef HAVE_SETRESUID
2018 if (0 != setresuid (uid, uid, uid))
2019 {
2020 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
2021 if (-1 != dev.fd_raw)
2022 (void) close (dev.fd_raw);
2023 return 1;
2024 }
2025#else
2026 if (0 != (setuid (uid) | seteuid (uid)))
2027 {
2028 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
2029 if (-1 != dev.fd_raw)
2030 (void) close (dev.fd_raw);
2031 return 1;
2032 }
2033#endif
2034 }
2035
2036
2037 /* send MAC address of the WLAN interface to STDOUT first */
2038 {
2039 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2040
2041 macmsg.hdr.size = htons (sizeof(macmsg));
2042 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2043 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
2044 GNUNET_TRANSPORT_WLAN_MacAddress));
2045 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
2046 write_std.size = sizeof(macmsg);
2047 }
2048
2049 stdin_mst = mst_create (&stdin_send_hw, &dev);
2050 stdin_open = 1;
2051 while (1)
2052 {
2053 maxfd = -1;
2054 FD_ZERO (&rfds);
2055 if ((0 == write_pout.size) && (1 == stdin_open))
2056 {
2057 FD_SET (STDIN_FILENO, &rfds);
2058 maxfd = MAX (maxfd, STDIN_FILENO);
2059 }
2060 if (0 == write_std.size)
2061 {
2062 FD_SET (dev.fd_raw, &rfds);
2063 maxfd = MAX (maxfd, dev.fd_raw);
2064 }
2065 FD_ZERO (&wfds);
2066 if (0 < write_std.size)
2067 {
2068 FD_SET (STDOUT_FILENO, &wfds);
2069 maxfd = MAX (maxfd, STDOUT_FILENO);
2070 }
2071 if (0 < write_pout.size)
2072 {
2073 FD_SET (dev.fd_raw, &wfds);
2074 maxfd = MAX (maxfd, dev.fd_raw);
2075 }
2076 {
2077 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
2078 if ((-1 == retval) && (EINTR == errno))
2079 continue;
2080 if (0 > retval)
2081 {
2082 fprintf (stderr, "select failed: %s\n", strerror (errno));
2083 break;
2084 }
2085 }
2086 if (FD_ISSET (STDOUT_FILENO, &wfds))
2087 {
2088 ssize_t ret =
2089 write (STDOUT_FILENO, write_std.buf + write_std.pos,
2090 write_std.size - write_std.pos);
2091 if (0 > ret)
2092 {
2093 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
2094 break;
2095 }
2096 write_std.pos += ret;
2097 if (write_std.pos == write_std.size)
2098 {
2099 write_std.pos = 0;
2100 write_std.size = 0;
2101 }
2102 }
2103 if (FD_ISSET (dev.fd_raw, &wfds))
2104 {
2105 ssize_t ret =
2106 write (dev.fd_raw, write_pout.buf + write_pout.pos,
2107 write_pout.size - write_pout.pos);
2108 if (0 > ret)
2109 {
2110 fprintf (stderr, "Failed to write to WLAN device: %s\n",
2111 strerror (errno));
2112 break;
2113 }
2114 write_pout.pos += ret;
2115 if ((write_pout.pos != write_pout.size) && (0 != ret))
2116 {
2117 /* we should not get partial sends with packet-oriented devices... */
2118 fprintf (stderr, "Write error, partial send: %u/%u\n",
2119 (unsigned int) write_pout.pos,
2120 (unsigned int) write_pout.size);
2121 break;
2122 }
2123 if (write_pout.pos == write_pout.size)
2124 {
2125 write_pout.pos = 0;
2126 write_pout.size = 0;
2127 }
2128 }
2129
2130 if (FD_ISSET (STDIN_FILENO, &rfds))
2131 {
2132 ssize_t ret =
2133 read (STDIN_FILENO, readbuf, sizeof(readbuf));
2134 if (0 > ret)
2135 {
2136 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
2137 break;
2138 }
2139 if (0 == ret)
2140 {
2141 /* stop reading... */
2142 stdin_open = 0;
2143 }
2144 mst_receive (stdin_mst, readbuf, ret);
2145 }
2146
2147 if (FD_ISSET (dev.fd_raw, &rfds))
2148 {
2149 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2150 ssize_t ret;
2151
2152 rrm = (struct
2153 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2154 ret =
2155 linux_read (&dev, (unsigned char *) &rrm->frame,
2156 sizeof(write_std.buf)
2157 - sizeof(struct
2158 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2159 + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2160 rrm);
2161 if (0 > ret)
2162 {
2163 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2164 break;
2165 }
2166 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2167 {
2168 write_std.size = ret
2169 + sizeof(struct
2170 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2171 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2172 rrm->header.size = htons (write_std.size);
2173 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2174 }
2175 }
2176 }
2177 /* Error handling, try to clean up a bit at least */
2178 mst_destroy (stdin_mst);
2179 (void) close (dev.fd_raw);
2180 return 1; /* we never exit 'normally' */
2181}
2182
2183
2184/* end of gnunet-helper-transport-wlan.c */