diff options
Diffstat (limited to 'src/transport/gnunet-helper-transport-wlan.c')
-rw-r--r-- | src/transport/gnunet-helper-transport-wlan.c | 1712 |
1 files changed, 1712 insertions, 0 deletions
diff --git a/src/transport/gnunet-helper-transport-wlan.c b/src/transport/gnunet-helper-transport-wlan.c new file mode 100644 index 000000000..0bc6d88ff --- /dev/null +++ b/src/transport/gnunet-helper-transport-wlan.c | |||
@@ -0,0 +1,1712 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2010, 2011 Christian Grothoff (and other contributing authors) | ||
4 | Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com> | ||
5 | Copyright (C) 2009 Thomas d'Otreppe | ||
6 | |||
7 | GNUnet is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published | ||
9 | by the Free Software Foundation; either version 3, or (at your | ||
10 | option) any later version. | ||
11 | |||
12 | GNUnet is distributed in the hope that it will be useful, but | ||
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with GNUnet; see the file COPYING. If not, write to the | ||
19 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
20 | Boston, MA 02111-1307, USA. | ||
21 | */ | ||
22 | /*- | ||
23 | * we use our local copy of ieee80211_radiotap.h | ||
24 | * | ||
25 | * - since we can't support extensions we don't understand | ||
26 | * - since linux does not include it in userspace headers | ||
27 | * | ||
28 | * Portions of this code were taken from the ieee80211_radiotap.h header, | ||
29 | * which is | ||
30 | * | ||
31 | * Copyright (c) 2003, 2004 David Young. All rights reserved. | ||
32 | * | ||
33 | * Redistribution and use in source and binary forms, with or without | ||
34 | * modification, are permitted provided that the following conditions | ||
35 | * are met: | ||
36 | * 1. Redistributions of source code must retain the above copyright | ||
37 | * notice, this list of conditions and the following disclaimer. | ||
38 | * 2. Redistributions in binary form must reproduce the above copyright | ||
39 | * notice, this list of conditions and the following disclaimer in the | ||
40 | * documentation and/or other materials provided with the distribution. | ||
41 | * 3. The name of David Young may not be used to endorse or promote | ||
42 | * products derived from this software without specific prior | ||
43 | * written permission. | ||
44 | * | ||
45 | * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY | ||
46 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
47 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
48 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID | ||
49 | * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
50 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||
51 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
52 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
53 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
54 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
55 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY | ||
56 | * OF SUCH DAMAGE. | ||
57 | */ | ||
58 | |||
59 | /* | ||
60 | * Modifications to fit into the linux IEEE 802.11 stack, | ||
61 | * Mike Kershaw (dragorn@kismetwireless.net) | ||
62 | */ | ||
63 | |||
64 | /** | ||
65 | * @file src/transport/gnunet-helper-transport-wlan.c | ||
66 | * @brief wlan layer two server; must run as root (SUID will do) | ||
67 | * This code will work under GNU/Linux only. | ||
68 | * @author David Brodski | ||
69 | * | ||
70 | * This program serves as the mediator between the wlan interface and | ||
71 | * gnunet | ||
72 | */ | ||
73 | |||
74 | /** | ||
75 | * parts taken from aircrack-ng, parts changend. | ||
76 | */ | ||
77 | #define _GNU_SOURCE | ||
78 | #include <sys/socket.h> | ||
79 | #include <sys/ioctl.h> | ||
80 | #include <sys/types.h> | ||
81 | #include <unistd.h> | ||
82 | #include <sys/wait.h> | ||
83 | #include <sys/time.h> | ||
84 | #include <sys/stat.h> | ||
85 | #include <netpacket/packet.h> | ||
86 | #include <linux/if_ether.h> | ||
87 | #include <linux/if.h> | ||
88 | #include <linux/wireless.h> | ||
89 | #include <netinet/in.h> | ||
90 | #include <linux/if_tun.h> | ||
91 | #include <stdio.h> | ||
92 | #include <stdlib.h> | ||
93 | #include <string.h> | ||
94 | #include <stdarg.h> | ||
95 | #include <fcntl.h> | ||
96 | #include <errno.h> | ||
97 | #include <dirent.h> | ||
98 | #include <sys/param.h> | ||
99 | #include <unistd.h> | ||
100 | #include <stdint.h> | ||
101 | |||
102 | #include "gnunet_protocols.h" | ||
103 | #include "plugin_transport_wlan.h" | ||
104 | |||
105 | #define ARPHRD_IEEE80211 801 | ||
106 | #define ARPHRD_IEEE80211_PRISM 802 | ||
107 | #define ARPHRD_IEEE80211_FULL 803 | ||
108 | |||
109 | /** | ||
110 | * size of 802.11 address | ||
111 | */ | ||
112 | #define IEEE80211_ADDR_LEN 6 | ||
113 | |||
114 | #define MAXLINE 4096 | ||
115 | |||
116 | #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000 | ||
117 | |||
118 | |||
119 | /* Name Data type Units | ||
120 | * ---- --------- ----- | ||
121 | * | ||
122 | * IEEE80211_RADIOTAP_TSFT __le64 microseconds | ||
123 | * | ||
124 | * Value in microseconds of the MAC's 64-bit 802.11 Time | ||
125 | * Synchronization Function timer when the first bit of the | ||
126 | * MPDU arrived at the MAC. For received frames, only. | ||
127 | * | ||
128 | * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap | ||
129 | * | ||
130 | * Tx/Rx frequency in MHz, followed by flags (see below). | ||
131 | * | ||
132 | * IEEE80211_RADIOTAP_FHSS __le16 see below | ||
133 | * | ||
134 | * For frequency-hopping radios, the hop set (first byte) | ||
135 | * and pattern (second byte). | ||
136 | * | ||
137 | * IEEE80211_RADIOTAP_RATE uint8_t 500kb/s | ||
138 | * | ||
139 | * Tx/Rx data rate | ||
140 | * | ||
141 | * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from | ||
142 | * one milliwatt (dBm) | ||
143 | * | ||
144 | * RF signal power at the antenna, decibel difference from | ||
145 | * one milliwatt. | ||
146 | * | ||
147 | * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from | ||
148 | * one milliwatt (dBm) | ||
149 | * | ||
150 | * RF noise power at the antenna, decibel difference from one | ||
151 | * milliwatt. | ||
152 | * | ||
153 | * IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB) | ||
154 | * | ||
155 | * RF signal power at the antenna, decibel difference from an | ||
156 | * arbitrary, fixed reference. | ||
157 | * | ||
158 | * IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB) | ||
159 | * | ||
160 | * RF noise power at the antenna, decibel difference from an | ||
161 | * arbitrary, fixed reference point. | ||
162 | * | ||
163 | * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless | ||
164 | * | ||
165 | * Quality of Barker code lock. Unitless. Monotonically | ||
166 | * nondecreasing with "better" lock strength. Called "Signal | ||
167 | * Quality" in datasheets. (Is there a standard way to measure | ||
168 | * this?) | ||
169 | * | ||
170 | * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless | ||
171 | * | ||
172 | * Transmit power expressed as unitless distance from max | ||
173 | * power set at factory calibration. 0 is max power. | ||
174 | * Monotonically nondecreasing with lower power levels. | ||
175 | * | ||
176 | * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB) | ||
177 | * | ||
178 | * Transmit power expressed as decibel distance from max power | ||
179 | * set at factory calibration. 0 is max power. Monotonically | ||
180 | * nondecreasing with lower power levels. | ||
181 | * | ||
182 | * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from | ||
183 | * one milliwatt (dBm) | ||
184 | * | ||
185 | * Transmit power expressed as dBm (decibels from a 1 milliwatt | ||
186 | * reference). This is the absolute power level measured at | ||
187 | * the antenna port. | ||
188 | * | ||
189 | * IEEE80211_RADIOTAP_FLAGS uint8_t bitmap | ||
190 | * | ||
191 | * Properties of transmitted and received frames. See flags | ||
192 | * defined below. | ||
193 | * | ||
194 | * IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index | ||
195 | * | ||
196 | * Unitless indication of the Rx/Tx antenna for this packet. | ||
197 | * The first antenna is antenna 0. | ||
198 | * | ||
199 | * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap | ||
200 | * | ||
201 | * Properties of received frames. See flags defined below. | ||
202 | * | ||
203 | * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap | ||
204 | * | ||
205 | * Properties of transmitted frames. See flags defined below. | ||
206 | * | ||
207 | * IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data | ||
208 | * | ||
209 | * Number of rts retries a transmitted frame used. | ||
210 | * | ||
211 | * IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data | ||
212 | * | ||
213 | * Number of unicast retries a transmitted frame used. | ||
214 | * | ||
215 | */ | ||
216 | enum RadiotapType | ||
217 | { | ||
218 | IEEE80211_RADIOTAP_TSFT = 0, | ||
219 | IEEE80211_RADIOTAP_FLAGS = 1, | ||
220 | IEEE80211_RADIOTAP_RATE = 2, | ||
221 | IEEE80211_RADIOTAP_CHANNEL = 3, | ||
222 | IEEE80211_RADIOTAP_FHSS = 4, | ||
223 | IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, | ||
224 | IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, | ||
225 | IEEE80211_RADIOTAP_LOCK_QUALITY = 7, | ||
226 | IEEE80211_RADIOTAP_TX_ATTENUATION = 8, | ||
227 | IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, | ||
228 | IEEE80211_RADIOTAP_DBM_TX_POWER = 10, | ||
229 | IEEE80211_RADIOTAP_ANTENNA = 11, | ||
230 | IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, | ||
231 | IEEE80211_RADIOTAP_DB_ANTNOISE = 13, | ||
232 | IEEE80211_RADIOTAP_RX_FLAGS = 14, | ||
233 | IEEE80211_RADIOTAP_TX_FLAGS = 15, | ||
234 | IEEE80211_RADIOTAP_RTS_RETRIES = 16, | ||
235 | IEEE80211_RADIOTAP_DATA_RETRIES = 17, | ||
236 | IEEE80211_RADIOTAP_EXT = 31 | ||
237 | }; | ||
238 | |||
239 | /* For IEEE80211_RADIOTAP_FLAGS */ | ||
240 | #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received | ||
241 | * during CFP | ||
242 | */ | ||
243 | #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received | ||
244 | * with short | ||
245 | * preamble | ||
246 | */ | ||
247 | #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received | ||
248 | * with WEP encryption | ||
249 | */ | ||
250 | #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received | ||
251 | * with fragmentation | ||
252 | */ | ||
253 | #define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ | ||
254 | #define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between | ||
255 | * 802.11 header and payload | ||
256 | * (to 32-bit boundary) | ||
257 | */ | ||
258 | /* For IEEE80211_RADIOTAP_RX_FLAGS */ | ||
259 | #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */ | ||
260 | |||
261 | /* For IEEE80211_RADIOTAP_TX_FLAGS */ | ||
262 | #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive | ||
263 | * retries */ | ||
264 | #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */ | ||
265 | #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */ | ||
266 | #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* frame should not be ACKed */ | ||
267 | #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010 /* sequence number handled | ||
268 | * by userspace */ | ||
269 | |||
270 | |||
271 | /** | ||
272 | * A generic radio capture format is desirable. There is one for | ||
273 | * Linux, but it is neither rigidly defined (there were not even | ||
274 | * units given for some fields) nor easily extensible. | ||
275 | * | ||
276 | * I suggest the following extensible radio capture format. It is | ||
277 | * based on a bitmap indicating which fields are present. | ||
278 | * | ||
279 | * I am trying to describe precisely what the application programmer | ||
280 | * should expect in the following, and for that reason I tell the | ||
281 | * units and origin of each measurement (where it applies), or else I | ||
282 | * use sufficiently weaselly language ("is a monotonically nondecreasing | ||
283 | * function of...") that I cannot set false expectations for lawyerly | ||
284 | * readers. | ||
285 | * | ||
286 | * The radio capture header precedes the 802.11 header. | ||
287 | * All data in the header is little endian on all platforms. | ||
288 | */ | ||
289 | struct ieee80211_radiotap_header | ||
290 | { | ||
291 | /** | ||
292 | * Version 0. Only increases for drastic changes, introduction of | ||
293 | * compatible new fields does not count. | ||
294 | */ | ||
295 | uint8_t it_version; | ||
296 | uint8_t it_pad; | ||
297 | |||
298 | /** | ||
299 | * length of the whole header in bytes, including it_version, | ||
300 | * it_pad, it_len, and data fields. | ||
301 | */ | ||
302 | uint16_t it_len; | ||
303 | |||
304 | /** | ||
305 | * A bitmap telling which fields are present. Set bit 31 | ||
306 | * (0x80000000) to extend the bitmap by another 32 bits. Additional | ||
307 | * extensions are made by setting bit 31. | ||
308 | */ | ||
309 | uint32_t it_present; | ||
310 | }; | ||
311 | |||
312 | struct RadioTapheader | ||
313 | { | ||
314 | struct ieee80211_radiotap_header header; | ||
315 | uint8_t rate; | ||
316 | uint8_t pad1; | ||
317 | uint16_t txflags; | ||
318 | }; | ||
319 | |||
320 | |||
321 | /** | ||
322 | * FIXME. | ||
323 | */ | ||
324 | struct SendBuffer | ||
325 | { | ||
326 | unsigned int pos; | ||
327 | unsigned int size; | ||
328 | char buf[MAXLINE * 2]; | ||
329 | }; | ||
330 | |||
331 | |||
332 | /** | ||
333 | * generic definitions for IEEE 802.11 frames | ||
334 | */ | ||
335 | struct ieee80211_frame | ||
336 | { | ||
337 | uint8_t i_fc[2]; | ||
338 | uint8_t i_dur[2]; | ||
339 | uint8_t i_addr1[IEEE80211_ADDR_LEN]; | ||
340 | uint8_t i_addr2[IEEE80211_ADDR_LEN]; | ||
341 | uint8_t i_addr3[IEEE80211_ADDR_LEN]; | ||
342 | uint8_t i_seq[2]; | ||
343 | /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ | ||
344 | /* see below */ | ||
345 | } GNUNET_PACKED; | ||
346 | |||
347 | |||
348 | /** | ||
349 | * struct for storing the information of the hardware | ||
350 | */ | ||
351 | struct HardwareInfos | ||
352 | { | ||
353 | |||
354 | /** | ||
355 | * send buffer | ||
356 | */ | ||
357 | struct SendBuffer write_pout; | ||
358 | |||
359 | /** | ||
360 | * file descriptor for the raw socket | ||
361 | */ | ||
362 | int fd_raw; | ||
363 | |||
364 | int arptype_in; | ||
365 | |||
366 | /** | ||
367 | * Name of the interface, not necessarily 0-terminated (!). | ||
368 | */ | ||
369 | char iface[IFNAMSIZ]; | ||
370 | |||
371 | struct MacAddress pl_mac; | ||
372 | }; | ||
373 | |||
374 | |||
375 | |||
376 | |||
377 | /* *INDENT-OFF* */ | ||
378 | #define ___my_swab16(x) \ | ||
379 | ((u_int16_t)( \ | ||
380 | (((u_int16_t)(x) & (u_int16_t)0x00ffU) << 8) | \ | ||
381 | (((u_int16_t)(x) & (u_int16_t)0xff00U) >> 8) )) | ||
382 | |||
383 | #define ___my_swab32(x) \ | ||
384 | ((u_int32_t)( \ | ||
385 | (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \ | ||
386 | (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \ | ||
387 | (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \ | ||
388 | (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) )) | ||
389 | #define ___my_swab64(x) \ | ||
390 | ((u_int64_t)( \ | ||
391 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000000000ffULL) << 56) | \ | ||
392 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000000000ff00ULL) << 40) | \ | ||
393 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000000000ff0000ULL) << 24) | \ | ||
394 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00000000ff000000ULL) << 8) | \ | ||
395 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x000000ff00000000ULL) >> 8) | \ | ||
396 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x0000ff0000000000ULL) >> 24) | \ | ||
397 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0x00ff000000000000ULL) >> 40) | \ | ||
398 | (u_int64_t)(((u_int64_t)(x) & (u_int64_t)0xff00000000000000ULL) >> 56) )) | ||
399 | /* *INDENT-ON* */ | ||
400 | |||
401 | |||
402 | /** | ||
403 | * struct ieee80211_radiotap_iterator - tracks walk through present radiotap args | ||
404 | */ | ||
405 | struct ieee80211_radiotap_iterator | ||
406 | { | ||
407 | /** | ||
408 | * pointer to the radiotap header we are walking through | ||
409 | */ | ||
410 | const struct ieee80211_radiotap_header *rtheader; | ||
411 | |||
412 | /** | ||
413 | * length of radiotap header in cpu byte ordering | ||
414 | */ | ||
415 | size_t max_length; | ||
416 | |||
417 | /** | ||
418 | * IEEE80211_RADIOTAP_... index of current arg | ||
419 | */ | ||
420 | unsigned int this_arg_index; | ||
421 | |||
422 | /** | ||
423 | * pointer to current radiotap arg | ||
424 | */ | ||
425 | uint8_t *this_arg; | ||
426 | |||
427 | /** | ||
428 | * internal next argument index | ||
429 | */ | ||
430 | unsigned int arg_index; | ||
431 | |||
432 | /** | ||
433 | * internal next argument pointer | ||
434 | */ | ||
435 | uint8_t *arg; | ||
436 | |||
437 | /** | ||
438 | * internal pointer to next present uint32_t | ||
439 | */ | ||
440 | uint32_t *next_bitmap; | ||
441 | |||
442 | /** | ||
443 | * internal shifter for curr uint32_t bitmap, b0 set == arg present | ||
444 | */ | ||
445 | uint32_t bitmap_shifter; | ||
446 | }; | ||
447 | |||
448 | |||
449 | |||
450 | /* specialized version of server_mst.c begins here */ | ||
451 | |||
452 | #define ALIGN_FACTOR 8 | ||
453 | |||
454 | /** | ||
455 | * Smallest supported message. | ||
456 | */ | ||
457 | #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader) | ||
458 | |||
459 | |||
460 | /** | ||
461 | * Functions with this signature are called whenever a | ||
462 | * complete message is received by the tokenizer. | ||
463 | * | ||
464 | * @param cls closure | ||
465 | * @param message the actual message | ||
466 | */ | ||
467 | typedef void (*MessageTokenizerCallback) (void *cls, | ||
468 | const struct | ||
469 | GNUNET_MessageHeader * | ||
470 | message); | ||
471 | |||
472 | /** | ||
473 | * Handle to a message stream tokenizer. | ||
474 | */ | ||
475 | struct MessageStreamTokenizer | ||
476 | { | ||
477 | |||
478 | /** | ||
479 | * Function to call on completed messages. | ||
480 | */ | ||
481 | MessageTokenizerCallback cb; | ||
482 | |||
483 | /** | ||
484 | * Closure for cb. | ||
485 | */ | ||
486 | void *cb_cls; | ||
487 | |||
488 | /** | ||
489 | * Size of the buffer (starting at 'hdr'). | ||
490 | */ | ||
491 | size_t curr_buf; | ||
492 | |||
493 | /** | ||
494 | * How many bytes in buffer have we already processed? | ||
495 | */ | ||
496 | size_t off; | ||
497 | |||
498 | /** | ||
499 | * How many bytes in buffer are valid right now? | ||
500 | */ | ||
501 | size_t pos; | ||
502 | |||
503 | /** | ||
504 | * Beginning of the buffer. Typed like this to force alignment. | ||
505 | */ | ||
506 | struct GNUNET_MessageHeader *hdr; | ||
507 | |||
508 | }; | ||
509 | |||
510 | |||
511 | |||
512 | /** | ||
513 | * Create a message stream tokenizer. | ||
514 | * | ||
515 | * @param cb function to call on completed messages | ||
516 | * @param cb_cls closure for cb | ||
517 | * @return handle to tokenizer | ||
518 | */ | ||
519 | static struct MessageStreamTokenizer * | ||
520 | mst_create (MessageTokenizerCallback cb, | ||
521 | void *cb_cls) | ||
522 | { | ||
523 | struct MessageStreamTokenizer *ret; | ||
524 | |||
525 | ret = malloc (sizeof (struct MessageStreamTokenizer)); | ||
526 | if (NULL == ret) | ||
527 | exit (1); | ||
528 | ret->hdr = malloc (MIN_BUFFER_SIZE); | ||
529 | if (NULL == ret->hdr) | ||
530 | exit (2); | ||
531 | ret->curr_buf = MIN_BUFFER_SIZE; | ||
532 | ret->cb = cb; | ||
533 | ret->cb_cls = cb_cls; | ||
534 | return ret; | ||
535 | } | ||
536 | |||
537 | |||
538 | /** | ||
539 | * Add incoming data to the receive buffer and call the | ||
540 | * callback for all complete messages. | ||
541 | * | ||
542 | * @param mst tokenizer to use | ||
543 | * @param buf input data to add | ||
544 | * @param size number of bytes in buf | ||
545 | * @return GNUNET_OK if we are done processing (need more data) | ||
546 | * GNUNET_SYSERR if the data stream is corrupt | ||
547 | */ | ||
548 | static int | ||
549 | mst_receive (struct MessageStreamTokenizer *mst, | ||
550 | const char *buf, size_t size) | ||
551 | { | ||
552 | const struct GNUNET_MessageHeader *hdr; | ||
553 | size_t delta; | ||
554 | uint16_t want; | ||
555 | char *ibuf; | ||
556 | int need_align; | ||
557 | unsigned long offset; | ||
558 | int ret; | ||
559 | |||
560 | ret = GNUNET_OK; | ||
561 | ibuf = (char *) mst->hdr; | ||
562 | while (mst->pos > 0) | ||
563 | { | ||
564 | do_align: | ||
565 | if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) || | ||
566 | (0 != (mst->off % ALIGN_FACTOR))) | ||
567 | { | ||
568 | /* need to align or need more space */ | ||
569 | mst->pos -= mst->off; | ||
570 | memmove (ibuf, &ibuf[mst->off], mst->pos); | ||
571 | mst->off = 0; | ||
572 | } | ||
573 | if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) | ||
574 | { | ||
575 | delta = | ||
576 | GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) - | ||
577 | (mst->pos - mst->off), size); | ||
578 | memcpy (&ibuf[mst->pos], buf, delta); | ||
579 | mst->pos += delta; | ||
580 | buf += delta; | ||
581 | size -= delta; | ||
582 | } | ||
583 | if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader)) | ||
584 | { | ||
585 | return GNUNET_OK; | ||
586 | } | ||
587 | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | ||
588 | want = ntohs (hdr->size); | ||
589 | if (want < sizeof (struct GNUNET_MessageHeader)) | ||
590 | { | ||
591 | // GNUNET_break_op (0); | ||
592 | return GNUNET_SYSERR; | ||
593 | } | ||
594 | if (mst->curr_buf - mst->off < want) | ||
595 | { | ||
596 | /* need more space */ | ||
597 | mst->pos -= mst->off; | ||
598 | memmove (ibuf, &ibuf[mst->off], mst->pos); | ||
599 | mst->off = 0; | ||
600 | } | ||
601 | if (want > mst->curr_buf) | ||
602 | { | ||
603 | mst->hdr = realloc (mst->hdr, want); | ||
604 | if (NULL == mst->hdr) | ||
605 | exit (3); | ||
606 | ibuf = (char *) mst->hdr; | ||
607 | mst->curr_buf = want; | ||
608 | } | ||
609 | hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off]; | ||
610 | if (mst->pos - mst->off < want) | ||
611 | { | ||
612 | delta = GNUNET_MIN (want - (mst->pos - mst->off), size); | ||
613 | memcpy (&ibuf[mst->pos], buf, delta); | ||
614 | mst->pos += delta; | ||
615 | buf += delta; | ||
616 | size -= delta; | ||
617 | } | ||
618 | if (mst->pos - mst->off < want) | ||
619 | { | ||
620 | return GNUNET_OK; | ||
621 | } | ||
622 | mst->cb (mst->cb_cls, hdr); | ||
623 | mst->off += want; | ||
624 | if (mst->off == mst->pos) | ||
625 | { | ||
626 | /* reset to beginning of buffer, it's free right now! */ | ||
627 | mst->off = 0; | ||
628 | mst->pos = 0; | ||
629 | } | ||
630 | } | ||
631 | while (size > 0) | ||
632 | { | ||
633 | if (size < sizeof (struct GNUNET_MessageHeader)) | ||
634 | break; | ||
635 | offset = (unsigned long) buf; | ||
636 | need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO; | ||
637 | if (GNUNET_NO == need_align) | ||
638 | { | ||
639 | /* can try to do zero-copy and process directly from original buffer */ | ||
640 | hdr = (const struct GNUNET_MessageHeader *) buf; | ||
641 | want = ntohs (hdr->size); | ||
642 | if (want < sizeof (struct GNUNET_MessageHeader)) | ||
643 | { | ||
644 | // GNUNET_break_op (0); | ||
645 | mst->off = 0; | ||
646 | return GNUNET_SYSERR; | ||
647 | } | ||
648 | if (size < want) | ||
649 | break; /* or not, buffer incomplete, so copy to private buffer... */ | ||
650 | mst->cb (mst->cb_cls, hdr); | ||
651 | buf += want; | ||
652 | size -= want; | ||
653 | } | ||
654 | else | ||
655 | { | ||
656 | /* need to copy to private buffer to align; | ||
657 | * yes, we go a bit more spagetti than usual here */ | ||
658 | goto do_align; | ||
659 | } | ||
660 | } | ||
661 | if (size > 0) | ||
662 | { | ||
663 | if (size + mst->pos > mst->curr_buf) | ||
664 | { | ||
665 | mst->hdr = realloc (mst->hdr, size + mst->pos); | ||
666 | if (NULL == mst->hdr) | ||
667 | exit (4); | ||
668 | ibuf = (char *) mst->hdr; | ||
669 | mst->curr_buf = size + mst->pos; | ||
670 | } | ||
671 | // GNUNET_assert (mst->pos + size <= mst->curr_buf); | ||
672 | memcpy (&ibuf[mst->pos], buf, size); | ||
673 | mst->pos += size; | ||
674 | } | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | |||
679 | /** | ||
680 | * Destroys a tokenizer. | ||
681 | * | ||
682 | * @param mst tokenizer to destroy | ||
683 | */ | ||
684 | static void | ||
685 | mst_destroy (struct MessageStreamTokenizer *mst) | ||
686 | { | ||
687 | free (mst->hdr); | ||
688 | free (mst); | ||
689 | } | ||
690 | |||
691 | /* end of server_mst.c copy */ | ||
692 | |||
693 | |||
694 | |||
695 | |||
696 | /** | ||
697 | * Radiotap header iteration | ||
698 | * | ||
699 | * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator | ||
700 | * struct ieee80211_radiotap_iterator (no need to init the struct beforehand) | ||
701 | * then loop calling __ieee80211_radiotap_iterator_next()... it returns -1 | ||
702 | * if there are no more args in the header, or the next argument type index | ||
703 | * that is present. The iterator's this_arg member points to the start of the | ||
704 | * argument associated with the current argument index that is present, | ||
705 | * which can be found in the iterator's this_arg_index member. This arg | ||
706 | * index corresponds to the IEEE80211_RADIOTAP_... defines. | ||
707 | * | ||
708 | * @param iterator iterator to initialize | ||
709 | * @param radiotap_header message to parse | ||
710 | * @param max_length number of valid bytes in radiotap_header | ||
711 | * @return 0 on success | ||
712 | */ | ||
713 | static int | ||
714 | ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator, | ||
715 | const struct ieee80211_radiotap_header | ||
716 | *radiotap_header, | ||
717 | size_t max_length) | ||
718 | { | ||
719 | if ( (iterator == NULL) || | ||
720 | (radiotap_header == NULL) ) | ||
721 | return -EINVAL; | ||
722 | |||
723 | /* Linux only supports version 0 radiotap format */ | ||
724 | if (0 != radiotap_header->it_version) | ||
725 | return -EINVAL; | ||
726 | |||
727 | /* sanity check for allowed length and radiotap length field */ | ||
728 | if ( (max_length < sizeof (struct ieee80211_radiotap_header)) || | ||
729 | (max_length < (GNUNET_le16toh (radiotap_header->it_len))) ) | ||
730 | return -EINVAL; | ||
731 | |||
732 | iterator->rtheader = radiotap_header; | ||
733 | iterator->max_length = GNUNET_le16toh (radiotap_header->it_len); | ||
734 | iterator->arg_index = 0; | ||
735 | iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present); | ||
736 | iterator->arg = | ||
737 | ((uint8_t *) radiotap_header) + sizeof (struct ieee80211_radiotap_header); | ||
738 | iterator->this_arg = 0; | ||
739 | |||
740 | /* find payload start allowing for extended bitmap(s) */ | ||
741 | if ((iterator->bitmap_shifter & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) | ||
742 | { | ||
743 | while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & | ||
744 | IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) | ||
745 | { | ||
746 | iterator->arg += sizeof (uint32_t); | ||
747 | |||
748 | /* | ||
749 | * check for insanity where the present bitmaps | ||
750 | * keep claiming to extend up to or even beyond the | ||
751 | * stated radiotap header length | ||
752 | */ | ||
753 | if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length) | ||
754 | return -EINVAL; | ||
755 | } | ||
756 | iterator->arg += sizeof (uint32_t); | ||
757 | /* | ||
758 | * no need to check again for blowing past stated radiotap | ||
759 | * header length, becuase ieee80211_radiotap_iterator_next | ||
760 | * checks it before it is dereferenced | ||
761 | */ | ||
762 | } | ||
763 | /* we are all initialized happily */ | ||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | |||
768 | /** | ||
769 | * @brief ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg | ||
770 | * | ||
771 | * This function returns the next radiotap arg index (IEEE80211_RADIOTAP_...) | ||
772 | * and sets iterator->this_arg to point to the payload for the arg. It takes | ||
773 | * care of alignment handling and extended present fields. interator->this_arg | ||
774 | * can be changed by the caller. The args pointed to are in little-endian | ||
775 | * format. | ||
776 | * | ||
777 | * @param iterator: radiotap_iterator to move to next arg (if any) | ||
778 | * | ||
779 | * @return next present arg index on success or negative if no more or error | ||
780 | */ | ||
781 | static int | ||
782 | ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator) | ||
783 | { | ||
784 | |||
785 | /* | ||
786 | * small length lookup table for all radiotap types we heard of | ||
787 | * starting from b0 in the bitmap, so we can walk the payload | ||
788 | * area of the radiotap header | ||
789 | * | ||
790 | * There is a requirement to pad args, so that args | ||
791 | * of a given length must begin at a boundary of that length | ||
792 | * -- but note that compound args are allowed (eg, 2 x uint16_t | ||
793 | * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not | ||
794 | * a reliable indicator of alignment requirement. | ||
795 | * | ||
796 | * upper nybble: content alignment for arg | ||
797 | * lower nybble: content length for arg | ||
798 | */ | ||
799 | |||
800 | static const uint8_t rt_sizes[] = { | ||
801 | [IEEE80211_RADIOTAP_TSFT] = 0x88, | ||
802 | [IEEE80211_RADIOTAP_FLAGS] = 0x11, | ||
803 | [IEEE80211_RADIOTAP_RATE] = 0x11, | ||
804 | [IEEE80211_RADIOTAP_CHANNEL] = 0x24, | ||
805 | [IEEE80211_RADIOTAP_FHSS] = 0x22, | ||
806 | [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11, | ||
807 | [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11, | ||
808 | [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22, | ||
809 | [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22, | ||
810 | [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22, | ||
811 | [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11, | ||
812 | [IEEE80211_RADIOTAP_ANTENNA] = 0x11, | ||
813 | [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11, | ||
814 | [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11, | ||
815 | [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22, | ||
816 | [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22, | ||
817 | [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11, | ||
818 | [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11 | ||
819 | /* | ||
820 | * add more here as they are defined in | ||
821 | * include/net/ieee80211_radiotap.h | ||
822 | */ | ||
823 | }; | ||
824 | |||
825 | /* | ||
826 | * for every radiotap entry we can at | ||
827 | * least skip (by knowing the length)... | ||
828 | */ | ||
829 | |||
830 | while (iterator->arg_index < sizeof (rt_sizes)) | ||
831 | { | ||
832 | int hit = 0; | ||
833 | |||
834 | if (!(iterator->bitmap_shifter & 1)) | ||
835 | goto next_entry; /* arg not present */ | ||
836 | |||
837 | /* | ||
838 | * arg is present, account for alignment padding | ||
839 | * 8-bit args can be at any alignment | ||
840 | * 16-bit args must start on 16-bit boundary | ||
841 | * 32-bit args must start on 32-bit boundary | ||
842 | * 64-bit args must start on 64-bit boundary | ||
843 | * | ||
844 | * note that total arg size can differ from alignment of | ||
845 | * elements inside arg, so we use upper nybble of length | ||
846 | * table to base alignment on | ||
847 | * | ||
848 | * also note: these alignments are ** relative to the | ||
849 | * start of the radiotap header **. There is no guarantee | ||
850 | * that the radiotap header itself is aligned on any | ||
851 | * kind of boundary. | ||
852 | */ | ||
853 | |||
854 | if ((((void *) iterator->arg) - | ||
855 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> 4) | ||
856 | - 1)) | ||
857 | iterator->arg_index += | ||
858 | (rt_sizes[iterator->arg_index] >> 4) - | ||
859 | ((((void *) iterator->arg) - | ||
860 | ((void *) iterator->rtheader)) & ((rt_sizes[iterator->arg_index] >> | ||
861 | 4) - 1)); | ||
862 | |||
863 | /* | ||
864 | * this is what we will return to user, but we need to | ||
865 | * move on first so next call has something fresh to test | ||
866 | */ | ||
867 | |||
868 | iterator->this_arg_index = iterator->arg_index; | ||
869 | iterator->this_arg = iterator->arg; | ||
870 | hit = 1; | ||
871 | |||
872 | /* internally move on the size of this arg */ | ||
873 | |||
874 | iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; | ||
875 | |||
876 | /* | ||
877 | * check for insanity where we are given a bitmap that | ||
878 | * claims to have more arg content than the length of the | ||
879 | * radiotap section. We will normally end up equalling this | ||
880 | * max_length on the last arg, never exceeding it. | ||
881 | */ | ||
882 | |||
883 | if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > | ||
884 | iterator->max_length) | ||
885 | return -EINVAL; | ||
886 | |||
887 | next_entry: | ||
888 | |||
889 | iterator->arg_index++; | ||
890 | if (((iterator->arg_index & 31) == 0)) | ||
891 | { | ||
892 | /* completed current uint32_t bitmap */ | ||
893 | if (iterator->bitmap_shifter & 1) | ||
894 | { | ||
895 | /* b31 was set, there is more */ | ||
896 | /* move to next uint32_t bitmap */ | ||
897 | iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap); | ||
898 | iterator->next_bitmap++; | ||
899 | } | ||
900 | else | ||
901 | { | ||
902 | /* no more bitmaps: end */ | ||
903 | iterator->arg_index = sizeof (rt_sizes); | ||
904 | } | ||
905 | } | ||
906 | else | ||
907 | { /* just try the next bit */ | ||
908 | iterator->bitmap_shifter >>= 1; | ||
909 | } | ||
910 | |||
911 | /* if we found a valid arg earlier, return it now */ | ||
912 | |||
913 | if (hit) | ||
914 | return iterator->this_arg_index; | ||
915 | |||
916 | } | ||
917 | |||
918 | /* we don't know how to handle any more args, we're done */ | ||
919 | return -1; | ||
920 | } | ||
921 | |||
922 | |||
923 | /** | ||
924 | * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin | ||
925 | * @param buffer pointer to buffer for the message | ||
926 | * @param mac pointer to the mac address | ||
927 | * @return number of bytes written | ||
928 | */ | ||
929 | static int | ||
930 | send_mac_to_plugin (char *buffer, struct MacAddress *mac) | ||
931 | { | ||
932 | struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg; | ||
933 | |||
934 | memcpy (&macmsg.mac, (char *) mac, sizeof (struct MacAddress)); | ||
935 | macmsg.hdr.size = htons (sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)); | ||
936 | macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL); | ||
937 | memcpy (buffer, &macmsg, sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage)); | ||
938 | return sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage); | ||
939 | } | ||
940 | |||
941 | |||
942 | /** | ||
943 | * Return the channel from the frequency (in Mhz) | ||
944 | * @param frequency of the channel | ||
945 | * @return number of the channel | ||
946 | */ | ||
947 | static int | ||
948 | get_channel_from_frequency (int frequency) | ||
949 | { | ||
950 | if (frequency >= 2412 && frequency <= 2472) | ||
951 | return (frequency - 2407) / 5; | ||
952 | if (frequency == 2484) | ||
953 | return 14; | ||
954 | if (frequency >= 5000 && frequency <= 6100) | ||
955 | return (frequency - 5000) / 5; | ||
956 | return -1; | ||
957 | } | ||
958 | |||
959 | |||
960 | /** | ||
961 | * function to calculate the crc, the start of the calculation | ||
962 | * @param buf buffer to calc the crc | ||
963 | * @param len len of the buffer | ||
964 | * @return crc sum | ||
965 | */ | ||
966 | static unsigned long | ||
967 | calc_crc_osdep (const unsigned char *buf, size_t len) | ||
968 | { | ||
969 | static const unsigned long int crc_tbl_osdep[256] = { | ||
970 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, | ||
971 | 0xE963A535, 0x9E6495A3, | ||
972 | 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, | ||
973 | 0xE7B82D07, 0x90BF1D91, | ||
974 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, | ||
975 | 0xF4D4B551, 0x83D385C7, | ||
976 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, | ||
977 | 0xFA0F3D63, 0x8D080DF5, | ||
978 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, | ||
979 | 0xD20D85FD, 0xA50AB56B, | ||
980 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, | ||
981 | 0xDCD60DCF, 0xABD13D59, | ||
982 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, | ||
983 | 0xCFBA9599, 0xB8BDA50F, | ||
984 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, | ||
985 | 0xC1611DAB, 0xB6662D3D, | ||
986 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, | ||
987 | 0x9FBFE4A5, 0xE8B8D433, | ||
988 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, | ||
989 | 0x91646C97, 0xE6635C01, | ||
990 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, | ||
991 | 0x8208F4C1, 0xF50FC457, | ||
992 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, | ||
993 | 0x8CD37CF3, 0xFBD44C65, | ||
994 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, | ||
995 | 0xA4D1C46D, 0xD3D6F4FB, | ||
996 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, | ||
997 | 0xAA0A4C5F, 0xDD0D7CC9, | ||
998 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, | ||
999 | 0xB966D409, 0xCE61E49F, | ||
1000 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, | ||
1001 | 0xB7BD5C3B, 0xC0BA6CAD, | ||
1002 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, | ||
1003 | 0x04DB2615, 0x73DC1683, | ||
1004 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, | ||
1005 | 0x0A00AE27, 0x7D079EB1, | ||
1006 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, | ||
1007 | 0x196C3671, 0x6E6B06E7, | ||
1008 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, | ||
1009 | 0x17B7BE43, 0x60B08ED5, | ||
1010 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, | ||
1011 | 0x3FB506DD, 0x48B2364B, | ||
1012 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, | ||
1013 | 0x316E8EEF, 0x4669BE79, | ||
1014 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, | ||
1015 | 0x220216B9, 0x5505262F, | ||
1016 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, | ||
1017 | 0x2CD99E8B, 0x5BDEAE1D, | ||
1018 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, | ||
1019 | 0x72076785, 0x05005713, | ||
1020 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, | ||
1021 | 0x7CDCEFB7, 0x0BDBDF21, | ||
1022 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, | ||
1023 | 0x6FB077E1, 0x18B74777, | ||
1024 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, | ||
1025 | 0x616BFFD3, 0x166CCF45, | ||
1026 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, | ||
1027 | 0x4969474D, 0x3E6E77DB, | ||
1028 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, | ||
1029 | 0x47B2CF7F, 0x30B5FFE9, | ||
1030 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, | ||
1031 | 0x54DE5729, 0x23D967BF, | ||
1032 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, | ||
1033 | 0x5A05DF1B, 0x2D02EF8D | ||
1034 | }; | ||
1035 | |||
1036 | unsigned long crc = 0xFFFFFFFF; | ||
1037 | |||
1038 | for (; len > 0; len--, buf++) | ||
1039 | crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8); | ||
1040 | return (~crc); | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | /** | ||
1045 | * Function to check crc of the wlan packet | ||
1046 | * @param buf buffer of the packet | ||
1047 | * @param len len of the data | ||
1048 | * @return crc sum of the data | ||
1049 | */ | ||
1050 | static int | ||
1051 | check_crc_buf_osdep (const unsigned char *buf, size_t len) | ||
1052 | { | ||
1053 | unsigned long crc; | ||
1054 | |||
1055 | if (0 > len) | ||
1056 | return 0; | ||
1057 | |||
1058 | crc = calc_crc_osdep (buf, len); | ||
1059 | buf += len; | ||
1060 | return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && | ||
1061 | ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); | ||
1062 | } | ||
1063 | |||
1064 | |||
1065 | /** | ||
1066 | * function to get the channel of a specific wlan card | ||
1067 | * @param dev pointer to the dev struct of the card | ||
1068 | * @return channel number | ||
1069 | */ | ||
1070 | static int | ||
1071 | linux_get_channel (const struct HardwareInfos *dev) | ||
1072 | { | ||
1073 | struct iwreq wrq; | ||
1074 | int fd; | ||
1075 | int frequency; | ||
1076 | int chan; | ||
1077 | |||
1078 | memset (&wrq, 0, sizeof (struct iwreq)); | ||
1079 | strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); | ||
1080 | fd = dev->fd_raw; | ||
1081 | if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) | ||
1082 | return -1; | ||
1083 | |||
1084 | frequency = wrq.u.freq.m; | ||
1085 | if (100000000 < frequency) | ||
1086 | frequency /= 100000; | ||
1087 | else if (1000000 < frequency) | ||
1088 | frequency /= 1000; | ||
1089 | if (1000 < frequency) | ||
1090 | chan = get_channel_from_frequency (frequency); | ||
1091 | else | ||
1092 | chan = frequency; | ||
1093 | return chan; | ||
1094 | } | ||
1095 | |||
1096 | |||
1097 | /** | ||
1098 | * function to read from a wlan card | ||
1099 | * @param dev pointer to the struct of the wlan card | ||
1100 | * @param buf buffer to read to | ||
1101 | * @param buf_size size of the buffer | ||
1102 | * @param ri radiotap_rx info | ||
1103 | * @return size read from the buffer | ||
1104 | */ | ||
1105 | static ssize_t | ||
1106 | linux_read (struct HardwareInfos *dev, unsigned char *buf, size_t buf_size, | ||
1107 | struct Radiotap_rx *ri) | ||
1108 | { | ||
1109 | unsigned char tmpbuf[buf_size]; | ||
1110 | ssize_t caplen; | ||
1111 | int n, got_signal, got_noise, got_channel, fcs_removed; | ||
1112 | |||
1113 | n = got_signal = got_noise = got_channel = fcs_removed = 0; | ||
1114 | |||
1115 | caplen = read (dev->fd_raw, tmpbuf, buf_size); | ||
1116 | if (0 > caplen) | ||
1117 | { | ||
1118 | if (EAGAIN == errno) | ||
1119 | return 0; | ||
1120 | fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno)); | ||
1121 | return -1; | ||
1122 | } | ||
1123 | |||
1124 | memset (buf, 0, buf_size); | ||
1125 | memset (ri, 0, sizeof (*ri)); | ||
1126 | |||
1127 | switch (dev->arptype_in) | ||
1128 | { | ||
1129 | case ARPHRD_IEEE80211_PRISM: | ||
1130 | { | ||
1131 | /* skip the prism header */ | ||
1132 | if (tmpbuf[7] == 0x40) | ||
1133 | { | ||
1134 | /* prism54 uses a different format */ | ||
1135 | ri->ri_power = tmpbuf[0x33]; | ||
1136 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); | ||
1137 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; | ||
1138 | got_signal = 1; | ||
1139 | got_noise = 1; | ||
1140 | n = 0x40; | ||
1141 | } | ||
1142 | else | ||
1143 | { | ||
1144 | ri->ri_mactime = *(uint64_t *) (tmpbuf + 0x5C - 48); | ||
1145 | ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); | ||
1146 | ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); | ||
1147 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); | ||
1148 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; | ||
1149 | got_channel = 1; | ||
1150 | got_signal = 1; | ||
1151 | got_noise = 1; | ||
1152 | n = *(int *) (tmpbuf + 4); | ||
1153 | } | ||
1154 | |||
1155 | if ( (n < 8) || (n >= caplen) ) | ||
1156 | return 0; | ||
1157 | } | ||
1158 | break; | ||
1159 | |||
1160 | case ARPHRD_IEEE80211_FULL: | ||
1161 | { | ||
1162 | struct ieee80211_radiotap_iterator iterator; | ||
1163 | struct ieee80211_radiotap_header *rthdr; | ||
1164 | |||
1165 | rthdr = (struct ieee80211_radiotap_header *) tmpbuf; | ||
1166 | |||
1167 | if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) | ||
1168 | return 0; | ||
1169 | |||
1170 | /* go through the radiotap arguments we have been given | ||
1171 | * by the driver | ||
1172 | */ | ||
1173 | |||
1174 | while (ieee80211_radiotap_iterator_next (&iterator) >= 0) | ||
1175 | { | ||
1176 | |||
1177 | switch (iterator.this_arg_index) | ||
1178 | { | ||
1179 | |||
1180 | case IEEE80211_RADIOTAP_TSFT: | ||
1181 | ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg)); | ||
1182 | break; | ||
1183 | |||
1184 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: | ||
1185 | if (!got_signal) | ||
1186 | { | ||
1187 | if (*iterator.this_arg < 127) | ||
1188 | ri->ri_power = *iterator.this_arg; | ||
1189 | else | ||
1190 | ri->ri_power = *iterator.this_arg - 255; | ||
1191 | |||
1192 | got_signal = 1; | ||
1193 | } | ||
1194 | break; | ||
1195 | |||
1196 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | ||
1197 | if (!got_signal) | ||
1198 | { | ||
1199 | if (*iterator.this_arg < 127) | ||
1200 | ri->ri_power = *iterator.this_arg; | ||
1201 | else | ||
1202 | ri->ri_power = *iterator.this_arg - 255; | ||
1203 | |||
1204 | got_signal = 1; | ||
1205 | } | ||
1206 | break; | ||
1207 | |||
1208 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: | ||
1209 | if (!got_noise) | ||
1210 | { | ||
1211 | if (*iterator.this_arg < 127) | ||
1212 | ri->ri_noise = *iterator.this_arg; | ||
1213 | else | ||
1214 | ri->ri_noise = *iterator.this_arg - 255; | ||
1215 | |||
1216 | got_noise = 1; | ||
1217 | } | ||
1218 | break; | ||
1219 | |||
1220 | case IEEE80211_RADIOTAP_DB_ANTNOISE: | ||
1221 | if (!got_noise) | ||
1222 | { | ||
1223 | if (*iterator.this_arg < 127) | ||
1224 | ri->ri_noise = *iterator.this_arg; | ||
1225 | else | ||
1226 | ri->ri_noise = *iterator.this_arg - 255; | ||
1227 | |||
1228 | got_noise = 1; | ||
1229 | } | ||
1230 | break; | ||
1231 | |||
1232 | case IEEE80211_RADIOTAP_ANTENNA: | ||
1233 | ri->ri_antenna = *iterator.this_arg; | ||
1234 | break; | ||
1235 | |||
1236 | case IEEE80211_RADIOTAP_CHANNEL: | ||
1237 | ri->ri_channel = *iterator.this_arg; | ||
1238 | got_channel = 1; | ||
1239 | break; | ||
1240 | |||
1241 | case IEEE80211_RADIOTAP_RATE: | ||
1242 | ri->ri_rate = (*iterator.this_arg) * 500000; | ||
1243 | break; | ||
1244 | |||
1245 | case IEEE80211_RADIOTAP_FLAGS: | ||
1246 | /* is the CRC visible at the end? | ||
1247 | * remove | ||
1248 | */ | ||
1249 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) | ||
1250 | { | ||
1251 | fcs_removed = 1; | ||
1252 | caplen -= 4; | ||
1253 | } | ||
1254 | |||
1255 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) | ||
1256 | return (0); | ||
1257 | |||
1258 | break; | ||
1259 | } | ||
1260 | } | ||
1261 | n = GNUNET_le16toh (rthdr->it_len); | ||
1262 | if (n <= 0 || n >= caplen) | ||
1263 | return 0; | ||
1264 | } | ||
1265 | break; | ||
1266 | case ARPHRD_IEEE80211: | ||
1267 | /* do nothing? */ | ||
1268 | break; | ||
1269 | default: | ||
1270 | errno = ENOTSUP; | ||
1271 | return -1; | ||
1272 | } | ||
1273 | |||
1274 | caplen -= n; | ||
1275 | |||
1276 | //detect fcs at the end, even if the flag wasn't set and remove it | ||
1277 | if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) | ||
1278 | { | ||
1279 | caplen -= 4; | ||
1280 | } | ||
1281 | memcpy (buf, tmpbuf + n, caplen); | ||
1282 | if (!got_channel) | ||
1283 | ri->ri_channel = linux_get_channel (dev); | ||
1284 | |||
1285 | return caplen; | ||
1286 | } | ||
1287 | |||
1288 | |||
1289 | /** | ||
1290 | * function to open the device for read/write | ||
1291 | * @param dev pointer to the device struct | ||
1292 | * @return 0 on success | ||
1293 | */ | ||
1294 | static int | ||
1295 | open_device_raw (struct HardwareInfos *dev) | ||
1296 | { | ||
1297 | struct ifreq ifr; | ||
1298 | struct iwreq wrq; | ||
1299 | struct packet_mreq mr; | ||
1300 | struct sockaddr_ll sll; | ||
1301 | |||
1302 | /* find the interface index */ | ||
1303 | memset (&ifr, 0, sizeof (ifr)); | ||
1304 | strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ); | ||
1305 | if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr)) | ||
1306 | { | ||
1307 | fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", | ||
1308 | IFNAMSIZ, dev->iface, strerror (errno)); | ||
1309 | return 1; | ||
1310 | } | ||
1311 | |||
1312 | /* lookup the hardware type */ | ||
1313 | memset (&sll, 0, sizeof (sll)); | ||
1314 | sll.sll_family = AF_PACKET; | ||
1315 | sll.sll_ifindex = ifr.ifr_ifindex; | ||
1316 | sll.sll_protocol = htons (ETH_P_ALL); | ||
1317 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) | ||
1318 | { | ||
1319 | fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", | ||
1320 | IFNAMSIZ, dev->iface, strerror (errno)); | ||
1321 | return 1; | ||
1322 | } | ||
1323 | |||
1324 | /* lookup iw mode */ | ||
1325 | memset (&wrq, 0, sizeof (struct iwreq)); | ||
1326 | strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); | ||
1327 | if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq)) | ||
1328 | { | ||
1329 | /* most probably not supported (ie for rtap ipw interface) * | ||
1330 | * so just assume its correctly set... */ | ||
1331 | wrq.u.mode = IW_MODE_MONITOR; | ||
1332 | } | ||
1333 | |||
1334 | if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && | ||
1335 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && | ||
1336 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || | ||
1337 | (wrq.u.mode != IW_MODE_MONITOR)) | ||
1338 | { | ||
1339 | fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n", | ||
1340 | IFNAMSIZ, dev->iface); | ||
1341 | return 1; | ||
1342 | } | ||
1343 | |||
1344 | /* Is interface st to up, broadcast & running ? */ | ||
1345 | if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) | ||
1346 | { | ||
1347 | /* Bring interface up */ | ||
1348 | ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; | ||
1349 | |||
1350 | if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) | ||
1351 | { | ||
1352 | fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", | ||
1353 | IFNAMSIZ, dev->iface, strerror (errno)); | ||
1354 | return 1; | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | /* bind the raw socket to the interface */ | ||
1359 | if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll))) | ||
1360 | { | ||
1361 | fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ, | ||
1362 | dev->iface, strerror (errno)); | ||
1363 | return 1; | ||
1364 | } | ||
1365 | |||
1366 | /* lookup the hardware type */ | ||
1367 | if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) | ||
1368 | { | ||
1369 | fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", | ||
1370 | IFNAMSIZ, dev->iface, strerror (errno)); | ||
1371 | return 1; | ||
1372 | } | ||
1373 | |||
1374 | memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); | ||
1375 | dev->arptype_in = ifr.ifr_hwaddr.sa_family; | ||
1376 | if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && | ||
1377 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && | ||
1378 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) | ||
1379 | { | ||
1380 | fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n", | ||
1381 | ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface); | ||
1382 | return 1; | ||
1383 | } | ||
1384 | |||
1385 | /* enable promiscuous mode */ | ||
1386 | memset (&mr, 0, sizeof (mr)); | ||
1387 | mr.mr_ifindex = sll.sll_ifindex; | ||
1388 | mr.mr_type = PACKET_MR_PROMISC; | ||
1389 | if (0 != | ||
1390 | setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, | ||
1391 | sizeof (mr))) | ||
1392 | { | ||
1393 | fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n", | ||
1394 | IFNAMSIZ, dev->iface); | ||
1395 | return 1; | ||
1396 | } | ||
1397 | |||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | |||
1402 | /** | ||
1403 | * function to prepare the helper, e.g. sockets, device... | ||
1404 | * @param dev struct for the device | ||
1405 | * @param iface name of the interface | ||
1406 | * @return 0 on success | ||
1407 | */ | ||
1408 | static int | ||
1409 | wlan_initialize (struct HardwareInfos *dev, const char *iface) | ||
1410 | { | ||
1411 | char strbuf[512]; | ||
1412 | struct stat sbuf; | ||
1413 | int ret; | ||
1414 | |||
1415 | dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); | ||
1416 | if (0 > dev->fd_raw) | ||
1417 | { | ||
1418 | fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno)); | ||
1419 | return 1; | ||
1420 | } | ||
1421 | if (dev->fd_raw >= FD_SETSIZE) | ||
1422 | { | ||
1423 | fprintf (stderr, "File descriptor too large for select (%d > %d)\n", | ||
1424 | dev->fd_raw, FD_SETSIZE); | ||
1425 | close (dev->fd_raw); | ||
1426 | return 1; | ||
1427 | } | ||
1428 | |||
1429 | /* mac80211 stack detection */ | ||
1430 | ret = | ||
1431 | snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", | ||
1432 | iface); | ||
1433 | if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) | ||
1434 | { | ||
1435 | fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface); | ||
1436 | close (dev->fd_raw); | ||
1437 | return 1; | ||
1438 | } | ||
1439 | strncpy (dev->iface, iface, IFNAMSIZ); | ||
1440 | if (0 != open_device_raw (dev)) | ||
1441 | { | ||
1442 | close (dev->fd_raw); | ||
1443 | return 1; | ||
1444 | } | ||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | |||
1449 | /** | ||
1450 | * Function to test incoming packets mac for being our own. | ||
1451 | * | ||
1452 | * @param uint8_taIeeeHeader buffer of the packet | ||
1453 | * @param dev the Hardware_Infos struct | ||
1454 | * @return 0 if mac belongs to us, 1 if mac is for another target | ||
1455 | */ | ||
1456 | static int | ||
1457 | mac_test (const struct ieee80211_frame *uint8_taIeeeHeader, | ||
1458 | const struct HardwareInfos *dev) | ||
1459 | { | ||
1460 | if (0 != memcmp (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE)) | ||
1461 | return 1; | ||
1462 | if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &dev->pl_mac, MAC_ADDR_SIZE)) | ||
1463 | return 0; | ||
1464 | if (0 == memcmp (uint8_taIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE)) | ||
1465 | return 0; | ||
1466 | return 1; | ||
1467 | } | ||
1468 | |||
1469 | |||
1470 | /** | ||
1471 | * function to set the wlan header to make attacks more difficult | ||
1472 | * @param uint8_taIeeeHeader pointer to the header of the packet | ||
1473 | * @param dev pointer to the Hardware_Infos struct | ||
1474 | */ | ||
1475 | static void | ||
1476 | mac_set (struct ieee80211_frame *uint8_taIeeeHeader, | ||
1477 | const struct HardwareInfos *dev) | ||
1478 | { | ||
1479 | uint8_taIeeeHeader->i_fc[0] = 0x08; | ||
1480 | uint8_taIeeeHeader->i_fc[1] = 0x00; | ||
1481 | memcpy (uint8_taIeeeHeader->i_addr2, &dev->pl_mac, MAC_ADDR_SIZE); | ||
1482 | memcpy (uint8_taIeeeHeader->i_addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE); | ||
1483 | } | ||
1484 | |||
1485 | |||
1486 | /** | ||
1487 | * function to process the data from the stdin | ||
1488 | * @param cls pointer to the device struct | ||
1489 | * @param hdr pointer to the start of the packet | ||
1490 | */ | ||
1491 | static void | ||
1492 | stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr) | ||
1493 | { | ||
1494 | struct HardwareInfos *dev = cls; | ||
1495 | struct SendBuffer *write_pout = &dev->write_pout; | ||
1496 | struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1]; | ||
1497 | struct ieee80211_frame *wlanheader; | ||
1498 | size_t sendsize; | ||
1499 | struct RadioTapheader rtheader; | ||
1500 | |||
1501 | rtheader.header.it_version = 0; /* radiotap version */ | ||
1502 | rtheader.header.it_len = GNUNET_htole16 (0x0c); /* radiotap header length */ | ||
1503 | rtheader.header.it_present = GNUNET_le16toh (0x00008004); /* our bitmap */ | ||
1504 | rtheader.rate = 0x00; | ||
1505 | rtheader.pad1 = 0x00; | ||
1506 | rtheader.txflags = | ||
1507 | GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); | ||
1508 | |||
1509 | sendsize = ntohs (hdr->size); | ||
1510 | if (sendsize < | ||
1511 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) | ||
1512 | { | ||
1513 | fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n"); | ||
1514 | exit (1); | ||
1515 | } | ||
1516 | sendsize -= | ||
1517 | sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); | ||
1518 | |||
1519 | if (MAXLINE < sendsize) | ||
1520 | { | ||
1521 | fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); | ||
1522 | exit (1); | ||
1523 | } | ||
1524 | if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) | ||
1525 | { | ||
1526 | fprintf (stderr, "Function stdin_send_hw: wrong packet type\n"); | ||
1527 | exit (1); | ||
1528 | } | ||
1529 | |||
1530 | rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader)); | ||
1531 | rtheader.rate = header->rate; | ||
1532 | memcpy (write_pout->buf, &rtheader, sizeof (rtheader)); | ||
1533 | memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize); | ||
1534 | /* payload contains MAC address, but we don't trust it, so we'll | ||
1535 | * overwrite it with OUR MAC address again to prevent mischief */ | ||
1536 | wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader)); | ||
1537 | mac_set (wlanheader, dev); | ||
1538 | write_pout->size = sendsize + sizeof (rtheader); | ||
1539 | } | ||
1540 | |||
1541 | |||
1542 | /** | ||
1543 | * main function of the helper | ||
1544 | * @param argc number of arguments | ||
1545 | * @param argv arguments | ||
1546 | * @return 0 on success, 1 on error | ||
1547 | */ | ||
1548 | int | ||
1549 | main (int argc, char *argv[]) | ||
1550 | { | ||
1551 | uid_t uid; | ||
1552 | struct HardwareInfos dev; | ||
1553 | char readbuf[MAXLINE]; | ||
1554 | struct SendBuffer write_std; | ||
1555 | ssize_t ret; | ||
1556 | int maxfd; | ||
1557 | fd_set rfds; | ||
1558 | fd_set wfds; | ||
1559 | int retval; | ||
1560 | int stdin_open; | ||
1561 | struct MessageStreamTokenizer *stdin_mst; | ||
1562 | |||
1563 | if (2 != argc) | ||
1564 | { | ||
1565 | fprintf (stderr, | ||
1566 | "You must specify the name of the interface as the first and only argument to this program.\n"); | ||
1567 | return 1; | ||
1568 | } | ||
1569 | if (0 != wlan_initialize (&dev, argv[1])) | ||
1570 | return 1; | ||
1571 | uid = getuid (); | ||
1572 | if (0 != setresuid (uid, uid, uid)) | ||
1573 | { | ||
1574 | fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); | ||
1575 | /* not critical, continue anyway */ | ||
1576 | } | ||
1577 | |||
1578 | dev.write_pout.size = 0; | ||
1579 | dev.write_pout.pos = 0; | ||
1580 | stdin_mst = mst_create (&stdin_send_hw, &dev); | ||
1581 | |||
1582 | /* send mac to STDOUT first */ | ||
1583 | write_std.pos = 0; | ||
1584 | write_std.size = send_mac_to_plugin ((char *) &write_std.buf, &dev.pl_mac); | ||
1585 | stdin_open = 1; | ||
1586 | |||
1587 | while (1) | ||
1588 | { | ||
1589 | maxfd = -1; | ||
1590 | FD_ZERO (&rfds); | ||
1591 | if ((0 == dev.write_pout.size) && (1 == stdin_open)) | ||
1592 | { | ||
1593 | FD_SET (STDIN_FILENO, &rfds); | ||
1594 | maxfd = MAX (maxfd, STDIN_FILENO); | ||
1595 | } | ||
1596 | if (0 == write_std.size) | ||
1597 | { | ||
1598 | FD_SET (dev.fd_raw, &rfds); | ||
1599 | maxfd = MAX (maxfd, dev.fd_raw); | ||
1600 | } | ||
1601 | FD_ZERO (&wfds); | ||
1602 | if (0 < write_std.size) | ||
1603 | { | ||
1604 | FD_SET (STDOUT_FILENO, &wfds); | ||
1605 | maxfd = MAX (maxfd, STDOUT_FILENO); | ||
1606 | } | ||
1607 | if (0 < dev.write_pout.size) | ||
1608 | { | ||
1609 | FD_SET (dev.fd_raw, &wfds); | ||
1610 | maxfd = MAX (maxfd, dev.fd_raw); | ||
1611 | } | ||
1612 | retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); | ||
1613 | if ((-1 == retval) && (EINTR == errno)) | ||
1614 | continue; | ||
1615 | if (0 > retval) | ||
1616 | { | ||
1617 | fprintf (stderr, "select failed: %s\n", strerror (errno)); | ||
1618 | break; | ||
1619 | } | ||
1620 | if (FD_ISSET (STDOUT_FILENO, &wfds)) | ||
1621 | { | ||
1622 | ret = | ||
1623 | write (STDOUT_FILENO, write_std.buf + write_std.pos, | ||
1624 | write_std.size - write_std.pos); | ||
1625 | if (0 > ret) | ||
1626 | { | ||
1627 | fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); | ||
1628 | break; | ||
1629 | } | ||
1630 | write_std.pos += ret; | ||
1631 | if (write_std.pos == write_std.size) | ||
1632 | { | ||
1633 | write_std.pos = 0; | ||
1634 | write_std.size = 0; | ||
1635 | } | ||
1636 | } | ||
1637 | if (FD_ISSET (dev.fd_raw, &wfds)) | ||
1638 | { | ||
1639 | ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size); | ||
1640 | if (0 > ret) | ||
1641 | { | ||
1642 | fprintf (stderr, "Failed to write to WLAN device: %s\n", | ||
1643 | strerror (errno)); | ||
1644 | break; | ||
1645 | } | ||
1646 | dev.write_pout.pos += ret; | ||
1647 | if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0)) | ||
1648 | { | ||
1649 | /* we should not get partial sends with packet-oriented devices... */ | ||
1650 | fprintf (stderr, "Write error, partial send: %u/%u\n", | ||
1651 | dev.write_pout.pos, dev.write_pout.size); | ||
1652 | break; | ||
1653 | } | ||
1654 | if (dev.write_pout.pos == dev.write_pout.size) | ||
1655 | { | ||
1656 | dev.write_pout.pos = 0; | ||
1657 | dev.write_pout.size = 0; | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | if (FD_ISSET (STDIN_FILENO, &rfds)) | ||
1662 | { | ||
1663 | ret = read (STDIN_FILENO, readbuf, sizeof (readbuf)); | ||
1664 | if (0 > ret) | ||
1665 | { | ||
1666 | fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno)); | ||
1667 | break; | ||
1668 | } | ||
1669 | if (0 == ret) | ||
1670 | { | ||
1671 | /* stop reading... */ | ||
1672 | stdin_open = 0; | ||
1673 | } | ||
1674 | mst_receive (stdin_mst, readbuf, ret); | ||
1675 | } | ||
1676 | |||
1677 | if (FD_ISSET (dev.fd_raw, &rfds)) | ||
1678 | { | ||
1679 | struct GNUNET_MessageHeader *header; | ||
1680 | struct Radiotap_rx *rxinfo; | ||
1681 | struct ieee80211_frame *datastart; | ||
1682 | |||
1683 | header = (struct GNUNET_MessageHeader *) write_std.buf; | ||
1684 | rxinfo = (struct Radiotap_rx *) &header[1]; | ||
1685 | datastart = (struct ieee80211_frame *) &rxinfo[1]; | ||
1686 | ret = | ||
1687 | linux_read (&dev, (unsigned char *) datastart, | ||
1688 | sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - | ||
1689 | sizeof (struct GNUNET_MessageHeader), rxinfo); | ||
1690 | if (0 > ret) | ||
1691 | { | ||
1692 | fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); | ||
1693 | break; | ||
1694 | } | ||
1695 | if ((0 < ret) && (0 == mac_test (datastart, &dev))) | ||
1696 | { | ||
1697 | write_std.size = | ||
1698 | ret + sizeof (struct GNUNET_MessageHeader) + | ||
1699 | sizeof (struct Radiotap_rx); | ||
1700 | header->size = htons (write_std.size); | ||
1701 | header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1702 | } | ||
1703 | } | ||
1704 | |||
1705 | } | ||
1706 | /* Error handling, try to clean up a bit at least */ | ||
1707 | mst_destroy (stdin_mst); | ||
1708 | close (dev.fd_raw); | ||
1709 | return 1; /* we never exit 'normally' */ | ||
1710 | } | ||
1711 | |||
1712 | /* end of gnunet-helper-transport-wlan.c */ | ||