diff options
Diffstat (limited to 'src/transport/gnunet-helper-transport-wlan.c')
-rw-r--r-- | src/transport/gnunet-helper-transport-wlan.c | 2165 |
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 | */ | ||
215 | struct 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 | */ | ||
245 | struct 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 | */ | ||
284 | enum 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 | */ | ||
559 | struct 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 | */ | ||
591 | struct 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 | */ | ||
635 | struct 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 | */ | ||
688 | struct 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 | */ | ||
716 | struct 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 | */ | ||
741 | static struct SendBuffer write_pout; | ||
742 | |||
743 | /** | ||
744 | * Buffer for data read from the wireless card to be transmitted to stdout. | ||
745 | */ | ||
746 | static 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 | */ | ||
770 | typedef void (*MessageTokenizerCallback) (void *cls, | ||
771 | const struct | ||
772 | GNUNET_MessageHeader * | ||
773 | message); | ||
774 | |||
775 | /** | ||
776 | * Handle to a message stream tokenizer. | ||
777 | */ | ||
778 | struct 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 | */ | ||
819 | static struct MessageStreamTokenizer * | ||
820 | mst_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 | */ | ||
854 | static int | ||
855 | mst_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 | { | ||
870 | do_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 | */ | ||
1002 | static void | ||
1003 | mst_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 | */ | ||
1032 | static int | ||
1033 | ieee80211_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 | */ | ||
1097 | static int | ||
1098 | ieee80211_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 | */ | ||
1245 | static unsigned long | ||
1246 | calc_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 | */ | ||
1331 | static int | ||
1332 | check_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 | */ | ||
1356 | static int | ||
1357 | get_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 | */ | ||
1375 | static int | ||
1376 | linux_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 | */ | ||
1407 | static ssize_t | ||
1408 | linux_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 | */ | ||
1639 | static int | ||
1640 | open_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 | */ | ||
1767 | static int | ||
1768 | test_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 | */ | ||
1795 | static int | ||
1796 | mac_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 | */ | ||
1820 | static void | ||
1821 | mac_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 | */ | ||
1838 | static void | ||
1839 | stdin_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, ðeader, 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 | */ | ||
1922 | int | ||
1923 | main (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 */ | ||