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