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