aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-transport-wlan-helper.c
diff options
context:
space:
mode:
authorDavid Brodski <david@brodski.eu>2011-03-28 21:52:47 +0000
committerDavid Brodski <david@brodski.eu>2011-03-28 21:52:47 +0000
commit76b1f350c95e6f4e28a0bc9d915f20e354fff1ab (patch)
tree939433ea0a6937ae5326539a62d1ea9e0ebb9597 /src/transport/gnunet-transport-wlan-helper.c
parentc31a1ce379ec7ade3225ddda0364cf09a65d1689 (diff)
downloadgnunet-76b1f350c95e6f4e28a0bc9d915f20e354fff1ab.tar.gz
gnunet-76b1f350c95e6f4e28a0bc9d915f20e354fff1ab.zip
First test of wlan driver, sends beacon every 2 seconds
Diffstat (limited to 'src/transport/gnunet-transport-wlan-helper.c')
-rw-r--r--src/transport/gnunet-transport-wlan-helper.c2043
1 files changed, 1083 insertions, 960 deletions
diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c
index 088a1fc85..5220ff067 100644
--- a/src/transport/gnunet-transport-wlan-helper.c
+++ b/src/transport/gnunet-transport-wlan-helper.c
@@ -1,22 +1,22 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors) 3 (C) 2010 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19 */
20 20
21/** 21/**
22 * @file src/transport/gnunet-transport-wlan-helper.c 22 * @file src/transport/gnunet-transport-wlan-helper.c
@@ -28,8 +28,36 @@
28 * gnunet 28 * gnunet
29 */ 29 */
30 30
31#include <sys/socket.h>
32#include <sys/ioctl.h>
33#include <sys/types.h>
34#include <sys/wait.h>
35#include <sys/time.h>
36#include <sys/stat.h>
37#include <netpacket/packet.h>
38#include <linux/if_ether.h>
39#include <linux/if.h>
40#include <linux/wireless.h>
41#include <netinet/in.h>
42#include <linux/if_tun.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47#include <fcntl.h>
48#include <errno.h>
49#include <dirent.h>
50//#include <sys/utsname.h>
51#include <sys/param.h>
31 52
32#include "platform.h" 53/*
54 //#include <resolv.h>
55 #include <string.h>
56 #include <utime.h>
57 //#include <unistd.h>
58 #include <getopt.h>
59 */
60//#include "platform.h"
33#include "gnunet_constants.h" 61#include "gnunet_constants.h"
34#include "gnunet_os_lib.h" 62#include "gnunet_os_lib.h"
35#include "gnunet_transport_plugin.h" 63#include "gnunet_transport_plugin.h"
@@ -39,15 +67,91 @@
39#include "gnunet_common.h" 67#include "gnunet_common.h"
40#include "gnunet-transport-wlan-helper.h" 68#include "gnunet-transport-wlan-helper.h"
41#include "gnunet_crypto_lib.h" 69#include "gnunet_crypto_lib.h"
42#include "ieee80211_radiotap.h" 70
43#include <pcap.h> 71#include <pcap.h>
44#include <stdio.h> 72#include <stdio.h>
45#include <stdlib.h> 73#include <stdlib.h>
46#include <sys/stat.h> 74#include <sys/stat.h>
47 75
76#include "wlan/radiotap-parser.h"
77/* radiotap-parser defines types like u8 that
78 * ieee80211_radiotap.h needs
79 *
80 * we use our local copy of ieee80211_radiotap.h
81 *
82 * - since we can't support extensions we don't understand
83 * - since linux does not include it in userspace headers
84 */
85#include "wlan/ieee80211_radiotap.h"
86#include "wlan/crctable_osdep.h"
87#include "wlan/loopback_helper.h"
88
89#define ARPHRD_IEEE80211 801
90#define ARPHRD_IEEE80211_PRISM 802
91#define ARPHRD_IEEE80211_FULL 803
48 92
93int first;
94int closeprog;
49 95
96#include "wlan/helper_common.h"
97#include "wlan/loopback_helper.h"
50 98
99#define DEBUG 1
100
101typedef enum
102{
103 DT_NULL = 0,
104 DT_WLANNG,
105 DT_HOSTAP,
106 DT_MADWIFI,
107 DT_MADWIFING,
108 DT_BCM43XX,
109 DT_ORINOCO,
110 DT_ZD1211RW,
111 DT_ACX,
112 DT_MAC80211_RT,
113 DT_AT76USB,
114 DT_IPW2200
115
116} DRIVER_TYPE;
117
118static const char * szaDriverTypes[] =
119 { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP",
120 [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG",
121 [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco",
122 [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX",
123 [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb",
124 [DT_IPW2200] = "ipw2200" };
125
126struct Hardware_Infos
127{
128
129 struct sendbuf *write_pout;
130 int fd_in, arptype_in;
131 int fd_out, arptype_out;
132 int fd_main;
133 int fd_rtc;
134
135 DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */
136
137 FILE *f_cap_in;
138
139 struct pcap_file_header pfh_in;
140
141 int sysfs_inject;
142 int channel;
143 int freq;
144 int rate;
145 int tx_power;
146 char *wlanctlng; /* XXX never set */
147 char *iwpriv;
148 char *iwconfig;
149 char *ifconfig;
150 char *iface;
151 char *main_if;
152 unsigned char pl_mac[6];
153 int inject_wlanng;
154};
51 155
52//#include "radiotap.h" 156//#include "radiotap.h"
53 157
@@ -57,20 +161,11 @@ char mac[] =
57 161
58/* wifi bitrate to use in 500kHz units */ 162/* wifi bitrate to use in 500kHz units */
59 163
60static const u8 u8aRatesToUse[] = { 164static const u8 u8aRatesToUse[] =
61 165 {
62 54*2, 166
63 48*2, 167 54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5
64 36*2, 168 2 * 2, 1 * 2 };
65 24*2,
66 18*2,
67 12*2,
68 9*2,
69 11*2,
70 11, // 5.5
71 2*2,
72 1*2
73};
74 169
75#define OFFSET_FLAGS 0x10 170#define OFFSET_FLAGS 0x10
76#define OFFSET_RATE 0x11 171#define OFFSET_RATE 0x11
@@ -78,809 +173,813 @@ static const u8 u8aRatesToUse[] = {
78// this is where we store a summary of the 173// this is where we store a summary of the
79// information from the radiotap header 174// information from the radiotap header
80 175
81typedef struct { 176typedef struct
82 int m_nChannel; 177{
83 int m_nChannelFlags; 178 int m_nChannel;
84 int m_nRate; 179 int m_nChannelFlags;
85 int m_nAntenna; 180 int m_nRate;
86 int m_nRadiotapFlags; 181 int m_nAntenna;
87} __attribute__((packed)) PENUMBRA_RADIOTAP_DATA; 182 int m_nRadiotapFlags;
183}__attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
88 184
89void 185static void
90Dump(u8 * pu8, int nLength) 186sigfunc_hw(int sig)
91{ 187{
92 char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1; 188 closeprog = 1;
93 unsigned char baaLast[2][16];
94 uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
95
96 buf = szBuf;
97 szChar[0] = '\0';
98
99 for (n = 0; n < nLength; n++) {
100 baaLast[(nLine&1)^1][n&0xf] = pu8[n];
101 if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
102 szChar[n&0xf] = '.';
103 else
104 szChar[n&0xf] = pu8[n];
105 szChar[(n&0xf)+1] = '\0';
106 nPos += sprintf(&sz[nPos], "%02X ",
107 baaLast[(nLine&1)^1][n&0xf]);
108 if ((n&15) != 15)
109 continue;
110 if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) {
111 nSameCount++;
112 } else {
113 if (nSameCount)
114 buf += sprintf(buf, "(repeated %d times)\n",
115 nSameCount);
116 buf += sprintf(buf, "%04x: %s %s\n",
117 nStart, sz, szChar);
118 nSameCount = 0;
119 printf("%s", szBuf);
120 buf = szBuf;
121 }
122 nPos = 0; nStart = n+1; nLine++;
123 fFirst = 0; sz[0] = '\0'; szChar[0] = '\0';
124 }
125 if (nSameCount)
126 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
127
128 buf += sprintf(buf, "%04x: %s", nStart, sz);
129 if (n & 0xf) {
130 *buf++ = ' ';
131 while (n & 0xf) {
132 buf += sprintf(buf, " ");
133 n++;
134 }
135 }
136 buf += sprintf(buf, "%s\n", szChar);
137 printf("%s", szBuf);
138} 189}
139 190
140
141void 191void
142usage() 192Dump(u8 * pu8, int nLength)
143{ 193{
144 printf( 194 char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
145 "Usage: wlan-hwd [options] <interface>\n\nOptions\n" 195 unsigned char baaLast[2][16];
146 "-f/--fcs Mark as having FCS (CRC) already\n" 196 uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
147 " (pkt ends with 4 x sacrificial - chars)\n"
148 "Example:\n"
149 " echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
150 " iwconfig mon0 mode monitor\n"
151 " ifconfig mon0 up\n"
152 " wlan-hwd mon0 Spam down mon0 with\n"
153 " radiotap header first\n"
154 "\n");
155 exit(1);
156}
157 197
158int flagHelp = 0, flagMarkWithFCS = 0; 198 buf = szBuf;
159int flagVerbose = 0; 199 szChar[0] = '\0';
160 200
201 for (n = 0; n < nLength; n++)
202 {
203 baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n];
204 if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
205 szChar[n & 0xf] = '.';
206 else
207 szChar[n & 0xf] = pu8[n];
208 szChar[(n & 0xf) + 1] = '\0';
209 nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]);
210 if ((n & 15) != 15)
211 continue;
212 if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst))
213 {
214 nSameCount++;
215 }
216 else
217 {
218 if (nSameCount)
219 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
220 buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar);
221 nSameCount = 0;
222 printf("%s", szBuf);
223 buf = szBuf;
224 }
225 nPos = 0;
226 nStart = n + 1;
227 nLine++;
228 fFirst = 0;
229 sz[0] = '\0';
230 szChar[0] = '\0';
231 }
232 if (nSameCount)
233 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
161 234
162/* 235 buf += sprintf(buf, "%04x: %s", nStart, sz);
163 * Radiotap parser 236 if (n & 0xf)
164 * 237 {
165 * Copyright 2007 Andy Green <andy@warmcat.com> 238 *buf++ = ' ';
166 */ 239 while (n & 0xf)
167 240 {
168/** 241 buf += sprintf(buf, " ");
169 * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization 242 n++;
170 * @param iterator: radiotap_iterator to initialize 243 }
171 * @param radiotap_header: radiotap header to parse 244 }
172 * @param max_length: total length we can parse into (eg, whole packet length) 245 buf += sprintf(buf, "%s\n", szChar);
173 * 246 printf("%s", szBuf);
174 * @return 0 or a negative error code if there is a problem. 247}
175 *
176 * This function initializes an opaque iterator struct which can then
177 * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
178 * argument which is present in the header. It knows about extended
179 * present headers and handles them.
180 *
181 * How to use:
182 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
183 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
184 * checking for a good 0 return code. Then loop calling
185 * __ieee80211_radiotap_iterator_next()... it returns either 0,
186 * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
187 * The iterator's this_arg member points to the start of the argument
188 * associated with the current argument index that is present, which can be
189 * found in the iterator's this_arg_index member. This arg index corresponds
190 * to the IEEE80211_RADIOTAP_... defines.
191 *
192 * Radiotap header length:
193 * You can find the CPU-endian total radiotap header length in
194 * iterator->max_length after executing ieee80211_radiotap_iterator_init()
195 * successfully.
196 *
197 * Example code:
198 * See Documentation/networking/radiotap-headers.txt
199 */
200 248
201int ieee80211_radiotap_iterator_init( 249void
202 struct ieee80211_radiotap_iterator *iterator, 250usage()
203 struct ieee80211_radiotap_header *radiotap_header,
204 int max_length)
205{ 251{
206 /* Linux only supports version 0 radiotap format */ 252 printf("Usage: wlan-hwd [options] <interface>\n\nOptions\n"
207 if (radiotap_header->it_version) 253 "-f/--fcs Mark as having FCS (CRC) already\n"
208 return -EINVAL; 254 " (pkt ends with 4 x sacrificial - chars)\n"
209 255 "Example:\n"
210 /* sanity check for allowed length and radiotap length field */ 256 " echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
211 if (max_length < le16_to_cpu(radiotap_header->it_len)) 257 " iwconfig mon0 mode monitor\n"
212 return -EINVAL; 258 " ifconfig mon0 up\n"
213 259 " wlan-hwd mon0 Spam down mon0 with\n"
214 iterator->rtheader = radiotap_header; 260 " radiotap header first\n"
215 iterator->max_length = le16_to_cpu(radiotap_header->it_len); 261 "\n");
216 iterator->arg_index = 0; 262 exit(1);
217 iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present);
218 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
219 iterator->this_arg = 0;
220
221 /* find payload start allowing for extended bitmap(s) */
222
223 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
224 while (le32_to_cpu(*((u32 *)iterator->arg)) &
225 (1<<IEEE80211_RADIOTAP_EXT)) {
226 iterator->arg += sizeof(u32);
227
228 /*
229 * check for insanity where the present bitmaps
230 * keep claiming to extend up to or even beyond the
231 * stated radiotap header length
232 */
233
234 if (((ulong)iterator->arg -
235 (ulong)iterator->rtheader) > iterator->max_length)
236 return -EINVAL;
237 }
238
239 iterator->arg += sizeof(u32);
240
241 /*
242 * no need to check again for blowing past stated radiotap
243 * header length, because ieee80211_radiotap_iterator_next
244 * checks it before it is dereferenced
245 */
246 }
247
248 /* we are all initialized happily */
249
250 return 0;
251} 263}
252 264
253 265void
254/** 266packet_callback(unsigned char *Args, const struct pcap_pkthdr* Pkthdr,
255 * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg 267 unsigned char *Packet)
256 * @param iterator: radiotap_iterator to move to next arg (if any)
257 *
258 * @return 0 if there is an argument to handle,
259 * -ENOENT if there are no more args or -EINVAL
260 * if there is something else wrong.
261 *
262 * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
263 * in this_arg_index and sets this_arg to point to the
264 * payload for the field. It takes care of alignment handling and extended
265 * present fields. this_arg can be changed by the caller (eg,
266 * incremented to move inside a compound argument like
267 * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
268 * little-endian format whatever the endianess of your CPU.
269 */
270
271int ieee80211_radiotap_iterator_next(
272 struct ieee80211_radiotap_iterator *iterator)
273{ 268{
274 269 fprintf(stderr, "+");
275 /* 270 fflush(stderr);
276 * small length lookup table for all radiotap types we heard of
277 * starting from b0 in the bitmap, so we can walk the payload
278 * area of the radiotap header
279 *
280 * There is a requirement to pad args, so that args
281 * of a given length must begin at a boundary of that length
282 * -- but note that compound args are allowed (eg, 2 x u16
283 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
284 * a reliable indicator of alignment requirement.
285 *
286 * upper nybble: content alignment for arg
287 * lower nybble: content length for arg
288 */
289
290 static const u8 rt_sizes[] = {
291 [IEEE80211_RADIOTAP_TSFT] = 0x88,
292 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
293 [IEEE80211_RADIOTAP_RATE] = 0x11,
294 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
295 [IEEE80211_RADIOTAP_FHSS] = 0x22,
296 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
297 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
298 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
299 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
300 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
301 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
302 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
303 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
304 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
305 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
306 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
307 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
308 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
309 /*
310 * add more here as they are defined in
311 * include/net/ieee80211_radiotap.h
312 */
313 };
314
315 /*
316 * for every radiotap entry we can at
317 * least skip (by knowing the length)...
318 */
319
320 while (iterator->arg_index < sizeof(rt_sizes)) {
321 int hit = 0;
322 int pad;
323
324 if (!(iterator->bitmap_shifter & 1))
325 goto next_entry; /* arg not present */
326
327 /*
328 * arg is present, account for alignment padding
329 * 8-bit args can be at any alignment
330 * 16-bit args must start on 16-bit boundary
331 * 32-bit args must start on 32-bit boundary
332 * 64-bit args must start on 64-bit boundary
333 *
334 * note that total arg size can differ from alignment of
335 * elements inside arg, so we use upper nybble of length
336 * table to base alignment on
337 *
338 * also note: these alignments are ** relative to the
339 * start of the radiotap header **. There is no guarantee
340 * that the radiotap header itself is aligned on any
341 * kind of boundary.
342 */
343
344 pad = (((ulong)iterator->arg) -
345 ((ulong)iterator->rtheader)) &
346 ((rt_sizes[iterator->arg_index] >> 4) - 1);
347
348 if (pad)
349 iterator->arg_index +=
350 (rt_sizes[iterator->arg_index] >> 4) - pad;
351
352 /*
353 * this is what we will return to user, but we need to
354 * move on first so next call has something fresh to test
355 */
356 iterator->this_arg_index = iterator->arg_index;
357 iterator->this_arg = iterator->arg;
358 hit = 1;
359
360 /* internally move on the size of this arg */
361 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
362
363 /*
364 * check for insanity where we are given a bitmap that
365 * claims to have more arg content than the length of the
366 * radiotap section. We will normally end up equalling this
367 * max_length on the last arg, never exceeding it.
368 */
369
370 if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
371 iterator->max_length)
372 return -EINVAL;
373
374 next_entry:
375 iterator->arg_index++;
376 if (unlikely((iterator->arg_index & 31) == 0)) {
377 /* completed current u32 bitmap */
378 if (iterator->bitmap_shifter & 1) {
379 /* b31 was set, there is more */
380 /* move to next u32 bitmap */
381 iterator->bitmap_shifter =
382 le32_to_cpu(*iterator->next_bitmap);
383 iterator->next_bitmap++;
384 } else {
385 /* no more bitmaps: end */
386 iterator->arg_index = sizeof(rt_sizes);
387 }
388 } else { /* just try the next bit */
389 iterator->bitmap_shifter >>= 1;
390 }
391
392 /* if we found a valid arg earlier, return it now */
393 if (hit)
394 return 0;
395 }
396
397 /* we don't know how to handle any more args, we're done */
398 return -ENOENT;
399} 271}
400 272
401#define FIFO_FILE1 "/tmp/MYFIFOin" 273unsigned long
402#define FIFO_FILE2 "/tmp/MYFIFOout" 274calc_crc_osdep(unsigned char * buf, int len)
403#define MAXLINE 4096 275{
276 unsigned long crc = 0xFFFFFFFF;
404 277
405static int first; 278 for (; len > 0; len--, buf++)
406static int closeprog; 279 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
407 280
408static void 281 return (~crc);
409sigfunc(int sig)
410{
411 closeprog = 1;
412 unlink(FIFO_FILE1);
413 unlink(FIFO_FILE2);
414} 282}
415 283
416struct sendbuf { 284/* CRC checksum verification routine */
417 int pos;
418 int size;
419 char buf[MAXLINE * 2];
420};
421 285
422static void 286int
423stdin_send (void *cls, 287check_crc_buf_osdep(unsigned char *buf, int len)
424 void *client,
425 const struct GNUNET_MessageHeader *hdr)
426{ 288{
427 struct sendbuf *write_pout = cls; 289 unsigned long crc;
428 int sendsize;
429 struct GNUNET_MessageHeader newheader;
430 char * from;
431 char * to;
432 290
433 sendsize = ntohs(hdr->size) - sizeof(struct RadiotapHeader) ; 291 if (len < 0)
292 return 0;
434 293
294 crc = calc_crc_osdep(buf, len);
295 buf += len;
296 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc
297 >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
298}
435 299
436 if(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)){ 300/* Search a file recursively */
437 fprintf(stderr, "Function stdin_send: wrong packet type\n"); 301static char *
438 exit(1); 302searchInside(const char * dir, const char * filename)
439 } 303{
440 if((sendsize + write_pout->size) > MAXLINE * 2){ 304 char * ret;
441 fprintf(stderr, "Function stdin_send: Packet too big for buffer\n"); 305 char * curfile;
442 exit(1); 306 struct stat sb;
443 } 307 int len, lentot;
308 DIR *dp;
309 struct dirent *ep;
310
311 dp = opendir(dir);
312 if (dp == NULL)
313 {
314 return NULL;
315 }
444 316
317 len = strlen(filename);
318 lentot = strlen(dir) + 256 + 2;
319 curfile = (char *) calloc(1, lentot);
445 320
446 newheader.size = htons(sendsize); 321 while ((ep = readdir(dp)) != NULL)
447 newheader.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); 322 {
448 323
324 memset(curfile, 0, lentot);
325 sprintf(curfile, "%s/%s", dir, ep->d_name);
449 326
450 to = write_pout->buf + write_pout->size; 327 //Checking if it's the good file
451 memcpy(to, &newheader, sizeof(struct GNUNET_MessageHeader)); 328 if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename))
452 write_pout->size += sizeof(struct GNUNET_MessageHeader); 329 {
330 (void) closedir(dp);
331 return curfile;
332 }
333 lstat(curfile, &sb);
453 334
454 from = ((char *) hdr) + sizeof(struct RadiotapHeader) + sizeof(struct GNUNET_MessageHeader); 335 //If it's a directory and not a link, try to go inside to search
455 to = write_pout->buf + write_pout->size; 336 if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
456 memcpy(to, from, sendsize - sizeof(struct GNUNET_MessageHeader)); 337 {
457 write_pout->size += sendsize - sizeof(struct GNUNET_MessageHeader); 338 //Check if the directory isn't "." or ".."
339 if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name))
340 {
341 //Recursive call
342 ret = searchInside(curfile, filename);
343 if (ret != NULL)
344 {
345 (void) closedir(dp);
346 free(curfile);
347 return ret;
348 }
349 }
350 }
351 }
352 (void) closedir(dp);
353 free(curfile);
354 return NULL;
458} 355}
459 356
460static void 357/* Search a wireless tool and return its path */
461file_in_send (void *cls, 358static char *
462 void *client, 359wiToolsPath(const char * tool)
463 const struct GNUNET_MessageHeader *hdr)
464{ 360{
465 struct sendbuf * write_std = cls; 361 char * path;
466 uint16_t sendsize; 362 int i, nbelems;
363 static const char * paths[] =
364 { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin",
365 "/usr/local/bin", "/tmp" };
467 366
468 sendsize = ntohs(hdr->size); 367 nbelems = sizeof(paths) / sizeof(char *);
469 368
470 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)) 369 for (i = 0; i < nbelems; i++)
471 { 370 {
472 fprintf (stderr, 371 path = searchInside(paths[i], tool);
473 "Function file_in_send: wrong packet type\n"); 372 if (path != NULL)
474 exit(1); 373 return path;
475 } 374 }
476 if((sendsize + write_std->size) > MAXLINE * 2){
477 fprintf(stderr, "Function file_in_send: Packet too big for buffer\n");
478 exit(1);
479 }
480 375
481 memcpy(write_std->buf + write_std->size, hdr, sendsize); 376 return NULL;
482 write_std->size += sendsize;
483} 377}
484 378
485/** 379static int
486 * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin 380linux_get_channel(struct Hardware_Infos *dev)
487 * @param buffer pointer to buffer for the message 381{
488 * @param mac pointer to the mac address 382 struct iwreq wrq;
489 * @return number of bytes written 383 int fd, frequency;
490 */ 384 int chan = 0;
491 385
492int 386 memset(&wrq, 0, sizeof(struct iwreq));
493send_mac_to_plugin(char* buffer, char * mac){
494 387
495 struct Wlan_Helper_Control_Message macmsg; 388 if (dev->main_if)
389 strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ );
390 else
391 strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
392
393 fd = dev->fd_in;
394 if (dev->drivertype == DT_IPW2200)
395 fd = dev->fd_main;
496 396
397 if (ioctl(fd, SIOCGIWFREQ, &wrq) < 0)
398 return (-1);
497 399
400 frequency = wrq.u.freq.m;
401 if (frequency > 100000000)
402 frequency /= 100000;
403 else if (frequency > 1000000)
404 frequency /= 1000;
498 405
499 memcpy(macmsg.mac.mac, mac, sizeof(struct MacAddress)); 406 if (frequency > 1000)
500 macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message)); 407 chan = getChannelFromFrequency(frequency);
501 macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL); 408 else
409 chan = frequency;
502 410
503 memcpy(buffer, &macmsg, sizeof(struct Wlan_Helper_Control_Message)); 411 return chan;
504 return sizeof(struct Wlan_Helper_Control_Message);
505} 412}
506 413
507int 414static int
508testmode(int argc, char *argv[]) 415linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count,
416 struct rx_info * ri)
509{ 417{
510 struct stat st; 418 unsigned char tmpbuf[4096];
511 int erg; 419
420 int caplen, n, got_signal, got_noise, got_channel, fcs_removed;
421
422 caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0;
423
424 if ((unsigned) count > sizeof(tmpbuf))
425 return (-1);
426 caplen = read(dev->fd_in, tmpbuf, count);
427 if (0 > caplen)
428 {
429 if (errno == EAGAIN)
430 return (0);
431
432 perror("read failed");
433 return (-1);
434 }
512 435
513 FILE *fpin; 436 memset(buf, 0, sizeof(buf));
514 FILE *fpout;
515 437
516 int fdpin; 438 /* XXX */
517 int fdpout; 439 if (ri)
440 memset(ri, 0, sizeof(*ri));
518 441
519 //make the fifos if needed 442 if (dev->arptype_in == ARPHRD_IEEE80211_PRISM)
520 if (0 != stat(FIFO_FILE1, &st))
521 { 443 {
522 if (0 == stat(FIFO_FILE2, &st)) 444 /* skip the prism header */
445 if (tmpbuf[7] == 0x40)
523 { 446 {
524 fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not\n"); 447 /* prism54 uses a different format */
525 exit(1); 448 if (ri)
449 {
450 ri->ri_power = tmpbuf[0x33];
451 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
452 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
453
454 got_signal = 1;
455 got_noise = 1;
456 }
457
458 n = 0x40;
526 } 459 }
460 else
461 {
462 if (ri)
463 {
464 ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48);
465 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
466 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
467 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
468 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
469
470 got_channel = 1;
471 got_signal = 1;
472 got_noise = 1;
473 }
527 474
528 umask(0); 475 n = *(int *) (tmpbuf + 4);
529 erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0); 476 }
530 erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
531 477
478 if (n < 8 || n >= caplen)
479 return (0);
532 } 480 }
533 else 481
482 if (dev->arptype_in == ARPHRD_IEEE80211_FULL)
534 { 483 {
484 struct ieee80211_radiotap_iterator iterator;
485 struct ieee80211_radiotap_header *rthdr;
486
487 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
488
489 if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0)
490 return (0);
535 491
536 if (0 != stat(FIFO_FILE2, &st)) 492 /* go through the radiotap arguments we have been given
493 * by the driver
494 */
495
496 while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0))
537 { 497 {
538 fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n"); 498
539 exit(1); 499 switch (iterator.this_arg_index)
500 {
501
502 case IEEE80211_RADIOTAP_TSFT:
503 ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg));
504 break;
505
506 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
507 if (!got_signal)
508 {
509 if (*iterator.this_arg < 127)
510 ri->ri_power = *iterator.this_arg;
511 else
512 ri->ri_power = *iterator.this_arg - 255;
513
514 got_signal = 1;
515 }
516 break;
517
518 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
519 if (!got_signal)
520 {
521 if (*iterator.this_arg < 127)
522 ri->ri_power = *iterator.this_arg;
523 else
524 ri->ri_power = *iterator.this_arg - 255;
525
526 got_signal = 1;
527 }
528 break;
529
530 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
531 if (!got_noise)
532 {
533 if (*iterator.this_arg < 127)
534 ri->ri_noise = *iterator.this_arg;
535 else
536 ri->ri_noise = *iterator.this_arg - 255;
537
538 got_noise = 1;
539 }
540 break;
541
542 case IEEE80211_RADIOTAP_DB_ANTNOISE:
543 if (!got_noise)
544 {
545 if (*iterator.this_arg < 127)
546 ri->ri_noise = *iterator.this_arg;
547 else
548 ri->ri_noise = *iterator.this_arg - 255;
549
550 got_noise = 1;
551 }
552 break;
553
554 case IEEE80211_RADIOTAP_ANTENNA:
555 ri->ri_antenna = *iterator.this_arg;
556 break;
557
558 case IEEE80211_RADIOTAP_CHANNEL:
559 ri->ri_channel = *iterator.this_arg;
560 got_channel = 1;
561 break;
562
563 case IEEE80211_RADIOTAP_RATE:
564 ri->ri_rate = (*iterator.this_arg) * 500000;
565 break;
566
567 case IEEE80211_RADIOTAP_FLAGS:
568 /* is the CRC visible at the end?
569 * remove
570 */
571 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
572 {
573 fcs_removed = 1;
574 caplen -= 4;
575 }
576
577 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
578 return (0);
579
580 break;
581
582 }
540 } 583 }
541 584
585 n = le16_to_cpu(rthdr->it_len);
586
587 if (n <= 0 || n >= caplen)
588 return (0);
542 } 589 }
543 590
544 if (strstr(argv[2], "1")) 591 caplen -= n;
592
593 //detect fcs at the end, even if the flag wasn't set and remove it
594 if (fcs_removed == 0 && check_crc_buf_osdep(tmpbuf + n, caplen - 4) == 1)
545 { 595 {
546 //fprintf(stderr, "First\n"); 596 caplen -= 4;
547 first = 1; 597 }
548 fpin = fopen(FIFO_FILE1, "r"); 598
549 if (NULL == fpin) 599 memcpy(buf, tmpbuf + n, caplen);
550 { 600
551 fprintf(stderr, "fopen of read FIFO_FILE1\n"); 601 if (ri && !got_channel)
552 exit(1); 602 ri->ri_channel = linux_get_channel(dev);
553 } 603
554 if (NULL == (fpout = fopen(FIFO_FILE2, "w"))) 604 return (caplen);
605}
606
607static int
608linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count)
609{
610 int ret, usedrtap = 0;
611 unsigned short int *p_rtlen;
612
613 unsigned char * u8aRadiotap = buf;
614
615 /* Pointer to the radiotap header length field for later use. */
616 p_rtlen = (unsigned short int*) (u8aRadiotap + 2);
617 usedrtap = 0;
618 ret = write(dev->fd_out, buf, count);
619
620 if (ret < 0)
621 {
622 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
623 == ENOMEM)
555 { 624 {
556 fprintf(stderr, "fopen of write FIFO_FILE2\n"); 625 usleep(10000);
557 exit(1); 626 return (0);
558 } 627 }
559 628
629 perror("write failed");
630 return (-1);
560 } 631 }
561 else 632
633 /* radiotap header length is stored little endian on all systems */
634 if (usedrtap)
635 ret -= letoh16(*p_rtlen);
636
637 if (ret < 0)
562 { 638 {
563 first = 0; 639 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
564 //fprintf(stderr, "Second\n"); 640 == ENOMEM)
565 if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
566 { 641 {
567 fprintf(stderr, "fopen of write FIFO_FILE1\n"); 642 usleep(10000);
568 exit(1); 643 return (0);
569 }
570 if (NULL == (fpin = fopen(FIFO_FILE2, "r")))
571 {
572 fprintf(stderr, "fopen of read FIFO_FILE2\n");
573 exit(1);
574 } 644 }
575 645
646 perror("write failed");
647 return (-1);
576 } 648 }
577 649
578 fdpin = fileno(fpin); 650 return (ret);
579 if (fdpin >= FD_SETSIZE) 651}
652
653static int
654openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype,
655 uint8_t *mac)
656{
657 struct ifreq ifr;
658 struct iwreq wrq;
659 struct packet_mreq mr;
660 struct sockaddr_ll sll;
661
662 /* find the interface index */
663
664 memset(&ifr, 0, sizeof(ifr));
665 strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
666
667 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
580 { 668 {
581 fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin, 669 printf("Interface %s: \n", iface);
582 (unsigned int) FD_SETSIZE); 670 perror("ioctl(SIOCGIFINDEX) failed");
583 close(fdpin); 671 return (1);
584 return -1;
585 } 672 }
586 673
587 fdpout = fileno(fpout); 674 memset(&sll, 0, sizeof(sll));
588 if (fdpout >= FD_SETSIZE) 675 sll.sll_family = AF_PACKET;
676 sll.sll_ifindex = ifr.ifr_ifindex;
677
678 switch (dev->drivertype)
589 { 679 {
590 fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout, 680 default:
591 (unsigned int) FD_SETSIZE); 681 sll.sll_protocol = htons(ETH_P_ALL);
592 close(fdpout); 682 break;
593 return -1; 683 }
594 684
685 /* lookup the hardware type */
686
687 if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
688 {
689 printf("Interface %s: \n", iface);
690 perror("ioctl(SIOCGIFHWADDR) failed");
691 return (1);
595 } 692 }
596 693
597 signal(SIGINT, &sigfunc); 694 /* lookup iw mode */
598 signal(SIGTERM, &sigfunc); 695 memset(&wrq, 0, sizeof(struct iwreq));
696 strncpy(wrq.ifr_name, iface, IFNAMSIZ);
599 697
600 char readbuf[MAXLINE]; 698 if (ioctl(fd, SIOCGIWMODE, &wrq) < 0)
601 int readsize = 0; 699 {
602 struct sendbuf write_std; 700 /* most probably not supported (ie for rtap ipw interface) *
603 write_std.size = 0; 701 * so just assume its correctly set... */
604 write_std.pos = 0; 702 wrq.u.mode = IW_MODE_MONITOR;
703 }
605 704
606 struct sendbuf write_pout; 705 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
607 write_pout.size = 0; 706 != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
608 write_pout.pos = 0; 707 != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR))
708 {
709 printf("Error: %s not in monitor mode\n", iface);
710 return (1);
711 }
609 712
610 int ret = 0; 713 /* Is interface st to up, broadcast & running ? */
611 int maxfd = 0; 714 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
715 {
716 /* Bring interface up*/
717 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
612 718
613 fd_set rfds; 719 if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
614 fd_set wfds; 720 {
615 struct timeval tv; 721 perror("ioctl(SIOCSIFFLAGS) failed");
616 int retval; 722 return (1);
723 }
724 }
725 /* bind the raw socket to the interface */
617 726
727 if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0)
728 {
729 printf("Interface %s: \n", iface);
730 perror("bind(ETH_P_ALL) failed");
731 return (1);
732 }
618 733
734 /* lookup the hardware type */
619 735
620 struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; 736 if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
621 struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst; 737 {
738 printf("Interface %s: \n", iface);
739 perror("ioctl(SIOCGIFHWADDR) failed");
740 return (1);
741 }
622 742
623 stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout); 743 memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6);
624 file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
625 744
626 //send mac first 745 *arptype = ifr.ifr_hwaddr.sa_family;
627 746
628 struct MacAddress macaddr; 747 if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
748 != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
749 != ARPHRD_IEEE80211_FULL)
750 {
751 if (ifr.ifr_hwaddr.sa_family == 1)
752 fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) ");
753 else
754 fprintf(stderr, "\nUnsupported hardware link type %4d ",
755 ifr.ifr_hwaddr.sa_family);
756
757 fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_"
758 "FULL or ARPHRD_IEEE80211_PRISM instead. Make\n"
759 "sure RFMON is enabled: run 'airmon-ng start %s"
760 " <#>'\nSysfs injection support was not found "
761 "either.\n\n", iface);
762 return (1);
763 }
629 764
630 //Send random mac address 765 /* enable promiscuous mode */
631 macaddr.mac[0] = 0x13;
632 macaddr.mac[1] = 0x22;
633 macaddr.mac[2] = 0x33;
634 macaddr.mac[3] = 0x44;
635 macaddr.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 256);
636 macaddr.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 256);
637 766
638 write_std.size = send_mac_to_plugin((char *) &write_std.buf, macaddr.mac); 767 memset(&mr, 0, sizeof(mr));
768 mr.mr_ifindex = sll.sll_ifindex;
769 mr.mr_type = PACKET_MR_PROMISC;
639 770
640 /* 771 if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
641 //wait 772 {
642 tv.tv_sec = 2; 773 perror("setsockopt(PACKET_MR_PROMISC) failed");
643 tv.tv_usec = 0; 774 return (1);
644 retval = select(0, NULL, NULL, NULL, &tv); 775 }
645 776
777 return (0);
778}
646 779
647 tv.tv_sec = 3; 780int
648 tv.tv_usec = 0; 781wlaninit(struct Hardware_Infos * dev, char *iface)
649 // if there is something to write 782{
650 FD_ZERO(&wfds);
651 FD_SET(STDOUT_FILENO, &wfds);
652 783
653 retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv); 784 char *iwpriv;
785 char strbuf[512];
786 dev->inject_wlanng = 1;
787 dev->rate = 2; /* default to 1Mbps if nothing is set */
654 788
655 if (FD_ISSET(STDOUT_FILENO, &wfds)) 789 /* open raw socks */
790 dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
791 if (0 > dev->fd_in)
656 { 792 {
657 ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size 793 perror("socket(PF_PACKET) failed at fd_in");
658 - write_std.pos); 794 if (getuid() != 0)
659 795 fprintf(stderr, "This program requires root privileges.\n");
660 if (0 > ret) 796 return (1);
661 {
662 closeprog = 1;
663 fprintf(stderr, "Write ERROR to STDOUT");
664 exit(1);
665 }
666 else
667 {
668 write_std.pos += ret;
669 // check if finished
670 if (write_std.pos == write_std.size)
671 {
672 write_std.pos = 0;
673 write_std.size = 0;
674 }
675 }
676 } 797 }
677 798
678 memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message)); 799 dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
679 write_std.size = sizeof(struct Wlan_Helper_Control_Message); 800 if (0 > dev->fd_main)
680 */
681
682 //wait
683 tv.tv_sec = 2;
684 tv.tv_usec = 0;
685 retval = select(0, NULL, NULL, NULL, &tv);
686
687 while (0 == closeprog)
688 { 801 {
802 perror("socket(PF_PACKET) failed at fd_main");
803 if (getuid() != 0)
804 fprintf(stderr, "This program requires root privileges.\n");
805 return (1);
806 }
689 807
690 maxfd = 0; 808 /* Check iwpriv existence */
691 809
692 //set timeout 810 iwpriv = wiToolsPath("iwpriv");
693 tv.tv_sec = 5; 811 dev->iwpriv = iwpriv;
694 tv.tv_usec = 0; 812 dev->iwconfig = wiToolsPath("iwconfig");
813 dev->ifconfig = wiToolsPath("ifconfig");
695 814
696 FD_ZERO(&rfds); 815 if (!iwpriv)
697 // if output queue is empty 816 {
698 if (0 == write_pout.size) 817 fprintf(stderr, "Can't find wireless tools, exiting.\n");
699 { 818 goto close_in;
700 FD_SET(STDIN_FILENO, &rfds); 819 }
701 820
702 } 821 dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
703 if (0 == write_std.size) 822 if (0 > dev->fd_out)
704 { 823 {
705 FD_SET(fdpin, &rfds); 824 perror("socket(PF_PACKET) failed at fd_out");
706 maxfd = fdpin; 825 goto close_in;
707 } 826 }
708 FD_ZERO(&wfds);
709 // if there is something to write
710 if (0 < write_std.size){
711 FD_SET(STDOUT_FILENO, &wfds);
712 maxfd = MAX(maxfd, STDOUT_FILENO);
713 }
714 827
715 if (0 < write_pout.size){ 828 /* figure out device type */
716 FD_SET(fdpout, &wfds);
717 maxfd = MAX(maxfd, fdpout);
718 }
719 829
830 /* mac80211 radiotap injection
831 * detected based on interface called mon...
832 * since mac80211 allows multiple virtual interfaces
833 *
834 * note though that the virtual interfaces are ultimately using a
835 * single physical radio: that means for example they must all
836 * operate on the same channel
837 */
720 838
721 retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv); 839 /* mac80211 stack detection */
840 memset(strbuf, 0, sizeof(strbuf));
841 snprintf(strbuf, sizeof(strbuf) - 1,
842 "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface);
722 843
723 if (-1 == retval && EINTR == errno) 844 if (system(strbuf) == 0)
724 { 845 dev->drivertype = DT_MAC80211_RT;
725 continue;
726 }
727 if (0 > retval)
728 {
729 fprintf(stderr, "select failed: %s\n", strerror(errno));
730 exit(1);
731 }
732 846
733 if (FD_ISSET(STDOUT_FILENO, &wfds)) 847 else
734 { 848 {
735 ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, 849 // At the moment only mac80211 tested
736 write_std.size - write_std.pos); 850 return 1;
851 }
737 852
738 if (0 > ret) 853#ifdef DEBUG
739 { 854 fprintf(stderr, "Interface %s -> driver: %s\n", iface,
740 closeprog = 1; 855 szaDriverTypes[dev->drivertype]);
741 fprintf(stderr, "Write ERROR to STDOUT\n"); 856#endif
742 exit(1);
743 }
744 else
745 {
746 write_std.pos += ret;
747 // check if finished
748 if (write_std.pos == write_std.size)
749 {
750 write_std.pos = 0;
751 write_std.size = 0;
752 }
753 }
754 }
755 857
756 if (FD_ISSET(fdpout, &wfds)) 858 if (openraw(dev, iface, dev->fd_out, &dev->arptype_out, dev->pl_mac) != 0)
757 { 859 {
758 ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size 860 goto close_out;
759 - write_pout.pos); 861 }
760 862
761 if (0 > ret) 863 dev->fd_in = dev->fd_out;
762 {
763 closeprog = 1;
764 fprintf(stderr, "Write ERROR to fdpout\n");
765 }
766 else
767 {
768 write_pout.pos += ret;
769 // check if finished
770 if (write_pout.pos == write_pout.size)
771 {
772 write_pout.pos = 0;
773 write_pout.size = 0;
774 }
775 }
776 }
777 864
778 if (FD_ISSET(STDIN_FILENO, &rfds)) 865 dev->arptype_in = dev->arptype_out;
779 {
780 readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
781 866
782 if (0 > readsize) 867 return 0;
783 { 868 close_out: close(dev->fd_out);
784 closeprog = 1; 869 close_in: close(dev->fd_in);
785 fprintf(stderr, "Read ERROR to STDIN_FILENO\n"); 870 return 1;
786 } 871}
787 else if (0 < readsize)
788 {
789 GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
790 GNUNET_NO, GNUNET_NO);
791 872
792 } 873static void
793 else 874stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
794 { 875{
795 //eof 876 struct Hardware_Infos * dev = cls;
796 closeprog = 1; 877 struct sendbuf *write_pout = dev->write_pout;
797 } 878 struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1];
798 } 879 int sendsize;
799 880
800 if (FD_ISSET(fdpin, &rfds)) 881 unsigned char u8aRadiotap[] =
801 { 882 { 0x00, 0x00, // <-- radiotap version
802 readsize = read(fdpin, readbuf, sizeof(readbuf)); 883 0x0c, 0x00, // <- radiotap header length
884 0x04, 0x80, 0x00, 0x00, // <-- bitmap
885 0x00, // <-- rate
886 0x00, // <-- padding for natural alignment
887 0x18, 0x00, // <-- TX flags
888 };
803 889
804 if (0 > readsize) 890 sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
805 { 891 - sizeof(struct GNUNET_MessageHeader);
806 closeprog = 1;
807 fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
808 closeprog = 1;
809 }
810 else if (0 < readsize)
811 {
812 GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
813 GNUNET_NO, GNUNET_NO);
814 892
815 } 893 if ((sendsize) > MAXLINE * 2)
816 else 894 {
817 { 895 fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
818 //eof 896 exit(1);
819 closeprog = 1; 897 }
820 }
821 }
822 898
899 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
900 {
901 fprintf(stderr, "Function stdin_send: wrong packet type\n");
902 exit(1);
823 } 903 }
824 904
825 //clean up 905 u8aRadiotap[8] = header->rate;
826 fclose(fpout);
827 fclose(fpin);
828 906
829 if (1 == first) 907 switch (dev->drivertype)
830 { 908 {
831 unlink(FIFO_FILE1); 909
832 unlink(FIFO_FILE2); 910 case DT_MAC80211_RT:
911 memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
912 memcpy(write_pout->buf + sizeof(u8aRadiotap), write_pout->buf
913 + sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader),
914 sendsize);
915 sendsize += sizeof(u8aRadiotap);
916
917 //usedrtap = 1;
918 break;
919 default:
920 break;
833 } 921 }
834 922
835 return (0); 923 write_pout->size = sendsize;
836} 924}
837 925
838void packet_callback(unsigned char *Args, 926int
839 const struct pcap_pkthdr* Pkthdr, 927maketest(unsigned char * buf)
840 unsigned char *Packet)
841{ 928{
842fprintf(stderr, "+"); fflush(stderr); 929 unsigned char u8aRadiotap[] =
843} 930 { 0x00, 0x00, // <-- radiotap version
931 0x0c, 0x00, // <- radiotap header length
932 0x04, 0x80, 0x00, 0x00, // <-- bitmap
933 0x00, // <-- rate
934 0x00, // <-- padding for natural alignment
935 0x18, 0x00, // <-- TX flags
936 };
937
938 static const uint8_t u8aIeeeHeader[] =
939 { 0x08, 0x01, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
940 // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
941 // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
942 0x00, 0x00, // Duration/ID
943 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac1 - in this case receiver
944 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac2 - in this case sender
945 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
946 0x10, 0x86, //Sequence Control
947 };
948
949 static const char txt[] = "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
950
951 u8aRadiotap[8] = 8;
952 memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap));
953 struct ieee80211_frame * ieee = (struct ieee80211_frame *) u8aIeeeHeader;
954 memcpy(buf + sizeof(u8aRadiotap), ieee, sizeof(u8aIeeeHeader));
955 memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt));
956 return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt);
844 957
958}
845 959
846int 960int
847hardwaremode(int argc, char *argv[]) 961hardwaremode(int argc, char *argv[])
848{ 962{
849 963
964 struct Hardware_Infos dev;
850 struct ifreq ifreq; 965 struct ifreq ifreq;
851 char mac[6]; 966 struct rx_info * rxinfo;
852 int SockFD; 967 uint8_t * mac = dev.pl_mac;
968 int fdpin, fdpout;
853 969
854 int fdpin; 970 signal(SIGINT, &sigfunc_hw);
855 int fdpout; 971 signal(SIGTERM, &sigfunc_hw);
856 972
857 pcap_t *ppcap = NULL; 973 if (wlaninit(&dev, argv[1]))
858 char szErrbuf[PCAP_ERRBUF_SIZE];
859
860 SockFD = socket(AF_INET, SOCK_DGRAM, 0);
861
862 strcpy(ifreq.ifr_name, argv[1]);
863 if (ioctl(SockFD, SIOCGIFHWADDR, &ifreq) < 0)
864 { 974 {
865 printf("SIOCGIFHWADDR(%s): %m\n", ifreq.ifr_name); 975 return 1;
866 return 0;
867 } 976 }
868 977
869 //copy mac to mac array
870 memcpy(mac, ifreq.ifr_hwaddr.sa_data, sizeof(struct MacAddress));
871
872 printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n", 978 printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",
873 ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3], 979 ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3],
874 (int) mac[4], (int) mac[5]); 980 (int) mac[4], (int) mac[5]);
875 981
876 return 0; 982 //return 0;
877 // open the interface in pcap
878 ppcap = pcap_open_live(argv[1], 800, 1, 20, szErrbuf);
879 if (ppcap == NULL)
880 {
881 printf("Unable to open interface %s in pcap: %s\n", argv[1], szErrbuf);
882 return (1);
883 }
884 983
885 char readbuf[MAXLINE]; 984 char readbuf[MAXLINE];
886 int readsize = 0; 985 int readsize = 0;
@@ -892,6 +991,8 @@ hardwaremode(int argc, char *argv[])
892 write_pout.size = 0; 991 write_pout.size = 0;
893 write_pout.pos = 0; 992 write_pout.pos = 0;
894 993
994 dev.write_pout = &write_pout;
995
895 int ret = 0; 996 int ret = 0;
896 int maxfd = 0; 997 int maxfd = 0;
897 998
@@ -901,13 +1002,11 @@ hardwaremode(int argc, char *argv[])
901 int retval; 1002 int retval;
902 1003
903 struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; 1004 struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
904 struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
905 1005
906 fdpin = pcap_fileno(ppcap); 1006 fdpin = dev.fd_in;
907 fdpout = pcap_fileno(ppcap); 1007 fdpout = dev.fd_out;
908 1008
909 stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout); 1009 stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
910 file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
911 1010
912 //send mac first 1011 //send mac first
913 1012
@@ -921,6 +1020,11 @@ hardwaremode(int argc, char *argv[])
921 while (0 == closeprog) 1020 while (0 == closeprog)
922 { 1021 {
923 1022
1023 write_pout.size = maketest(write_pout.buf);
1024 tv.tv_sec = 2;
1025 tv.tv_usec = 0;
1026 retval = select(0, NULL, NULL, NULL, &tv);
1027
924 maxfd = 0; 1028 maxfd = 0;
925 1029
926 //set timeout 1030 //set timeout
@@ -936,8 +1040,8 @@ hardwaremode(int argc, char *argv[])
936 } 1040 }
937 if (0 == write_std.size) 1041 if (0 == write_std.size)
938 { 1042 {
939 FD_SET(fdpin, &rfds); 1043 //FD_SET(fdpin, &rfds);
940 maxfd = fdpin; 1044 //maxfd = fdpin;
941 } 1045 }
942 FD_ZERO(&wfds); 1046 FD_ZERO(&wfds);
943 // if there is something to write 1047 // if there is something to write
@@ -990,8 +1094,10 @@ hardwaremode(int argc, char *argv[])
990 1094
991 if (FD_ISSET(fdpout, &wfds)) 1095 if (FD_ISSET(fdpout, &wfds))
992 { 1096 {
993 ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size 1097
994 - write_pout.pos); 1098 ret = linux_write(&dev, write_pout.buf, write_pout.size);
1099 //ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
1100 // - write_pout.pos);
995 1101
996 if (0 > ret) 1102 if (0 > ret)
997 { 1103 {
@@ -1002,11 +1108,17 @@ hardwaremode(int argc, char *argv[])
1002 { 1108 {
1003 write_pout.pos += ret; 1109 write_pout.pos += ret;
1004 // check if finished 1110 // check if finished
1005 if (write_pout.pos == write_pout.size) 1111 if (write_pout.pos != write_pout.size && ret != 0)
1112 {
1113 closeprog = 1;
1114 fprintf(stderr, "Write ERROR packet not in one piece send: %u, %u\n", write_pout.pos, write_pout.size);
1115 }
1116 else if (write_pout.pos == write_pout.size)
1006 { 1117 {
1007 write_pout.pos = 0; 1118 write_pout.pos = 0;
1008 write_pout.size = 0; 1119 write_pout.size = 0;
1009 } 1120 }
1121
1010 } 1122 }
1011 } 1123 }
1012 1124
@@ -1034,7 +1146,13 @@ hardwaremode(int argc, char *argv[])
1034 1146
1035 if (FD_ISSET(fdpin, &rfds)) 1147 if (FD_ISSET(fdpin, &rfds))
1036 { 1148 {
1037 readsize = read(fdpin, readbuf, sizeof(readbuf)); 1149 rxinfo = (struct rx_info *) (write_pout.buf
1150 + sizeof(struct GNUNET_MessageHeader));
1151 readsize = linux_read(&dev, (unsigned char *) readbuf
1152 + sizeof(struct rx_info) + sizeof(struct GNUNET_MessageHeader),
1153 sizeof(readbuf) - sizeof(struct rx_info)
1154 - sizeof(struct GNUNET_MessageHeader), rxinfo);
1155 //readsize = read(fdpin, readbuf, sizeof(readbuf));
1038 1156
1039 if (0 > readsize) 1157 if (0 > readsize)
1040 { 1158 {
@@ -1044,19 +1162,19 @@ hardwaremode(int argc, char *argv[])
1044 } 1162 }
1045 else if (0 < readsize) 1163 else if (0 < readsize)
1046 { 1164 {
1047 GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
1048 GNUNET_NO, GNUNET_NO);
1049 1165
1050 } 1166 }
1051 else 1167 else
1052 { 1168 {
1053 //eof 1169 //eof
1054 closeprog = 1; 1170 //closeprog = 1;
1055 } 1171 }
1056 } 1172 }
1057 1173
1058 } 1174 }
1059 1175
1176 return 0;
1177
1060} 1178}
1061 1179
1062int 1180int
@@ -1074,269 +1192,274 @@ main(int argc, char *argv[])
1074 { 1192 {
1075 1193
1076 return testmode(argc, argv); 1194 return testmode(argc, argv);
1077 } else { 1195 }
1196 else
1197 {
1078 hardwaremode(argc, argv); 1198 hardwaremode(argc, argv);
1079 } 1199 }
1080 1200
1081#if 0 1201#if 0
1082 u8 u8aSendBuffer[500]; 1202 u8 u8aSendBuffer[500];
1083 char szErrbuf[PCAP_ERRBUF_SIZE]; 1203 char szErrbuf[PCAP_ERRBUF_SIZE];
1084 int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0; 1204 int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
1085 int nOrdinal = 0, r, nDelay = 100000; 1205 int nOrdinal = 0, r, nDelay = 100000;
1086 int nRateIndex = 0, retval, bytes; 1206 int nRateIndex = 0, retval, bytes;
1087 pcap_t *ppcap = NULL; 1207 pcap_t *ppcap = NULL;
1088 struct bpf_program bpfprogram; 1208 struct bpf_program bpfprogram;
1089 char * szProgram = "", fBrokenSocket = 0; 1209 char * szProgram = "", fBrokenSocket = 0;
1090 u16 u16HeaderLen; 1210 u16 u16HeaderLen;
1091 char szHostname[PATH_MAX]; 1211 char szHostname[PATH_MAX];
1092 1212
1093 if (gethostname(szHostname, sizeof (szHostname) - 1)) { 1213 if (gethostname(szHostname, sizeof (szHostname) - 1))
1094 perror("unable to get hostname"); 1214 {
1095 } 1215 perror("unable to get hostname");
1096 szHostname[sizeof (szHostname) - 1] = '\0'; 1216 }
1097 1217 szHostname[sizeof (szHostname) - 1] = '\0';
1098 1218
1099 printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n"); 1219 printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
1100 1220
1101 while (1) { 1221 while (1)
1102 int nOptionIndex; 1222 {
1103 static const struct option optiona[] = { 1223 int nOptionIndex;
1104 { "delay", required_argument, NULL, 'd' }, 1224 static const struct option optiona[] =
1105 { "fcs", no_argument, &flagMarkWithFCS, 1 }, 1225 {
1106 { "help", no_argument, &flagHelp, 1 }, 1226 { "delay", required_argument, NULL, 'd'},
1107 { "verbose", no_argument, &flagVerbose, 1}, 1227 { "fcs", no_argument, &flagMarkWithFCS, 1},
1108 { 0, 0, 0, 0 } 1228 { "help", no_argument, &flagHelp, 1},
1109 }; 1229 { "verbose", no_argument, &flagVerbose, 1},
1110 int c = getopt_long(argc, argv, "d:hf", 1230 { 0, 0, 0, 0}
1111 optiona, &nOptionIndex); 1231 };
1112 1232 int c = getopt_long(argc, argv, "d:hf",
1113 if (c == -1) 1233 optiona, &nOptionIndex);
1114 break; 1234
1115 switch (c) { 1235 if (c == -1)
1116 case 0: // long option 1236 break;
1117 break; 1237 switch (c)
1118 1238 {
1119 case 'h': // help 1239 case 0: // long option
1120 usage(); 1240 break;
1121 1241
1122 case 'd': // delay 1242 case 'h': // help
1123 nDelay = atoi(optarg); 1243 usage();
1124 break; 1244
1125 1245 case 'd': // delay
1126 case 'f': // mark as FCS attached 1246 nDelay = atoi(optarg);
1127 flagMarkWithFCS = 1; 1247 break;
1128 break; 1248
1129 1249 case 'f': // mark as FCS attached
1130 case 'v': //Verbose / readable output to cout 1250 flagMarkWithFCS = 1;
1131 flagVerbose = 1; 1251 break;
1132 break; 1252
1133 1253 case 'v': //Verbose / readable output to cout
1134 default: 1254 flagVerbose = 1;
1135 printf("unknown switch %c\n", c); 1255 break;
1136 usage(); 1256
1137 break; 1257 default:
1138 } 1258 printf("unknown switch %c\n", c);
1139 } 1259 usage();
1140 1260 break;
1141 if (optind >= argc) 1261 }
1142 usage(); 1262 }
1143 1263
1144 1264 if (optind >= argc)
1145 // open the interface in pcap 1265 usage();
1146
1147 szErrbuf[0] = '\0';
1148 ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1149 if (ppcap == NULL) {
1150 printf("Unable to open interface %s in pcap: %s\n",
1151 argv[optind], szErrbuf);
1152 return (1);
1153 }
1154
1155 //get mac from interface
1156
1157 /*int sock, j, k;
1158 char mac[32];
1159
1160 sock=socket(PF_INET, SOCK_STREAM, 0);
1161 if (-1==sock) {
1162 perror("can not open socket\n");
1163 return 1;
1164 }
1165
1166 if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1167 perror("ioctl(SIOCGIFHWADDR) ");
1168 return 1;
1169 }
1170 for (j=0, k=0; j<6; j++) {
1171 k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
1172 (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
1173 }
1174 mac[sizeof(mac)-1]='\0';
1175 */
1176
1177 //get header type
1178 nLinkEncap = pcap_datalink(ppcap);
1179 nCaptureHeaderLength = 0;
1180
1181 switch (nLinkEncap) {
1182
1183 case DLT_PRISM_HEADER:
1184 printf("DLT_PRISM_HEADER Encap\n");
1185 nCaptureHeaderLength = 0x40;
1186 n80211HeaderLength = 0x20; // ieee80211 comes after this
1187 szProgram = "radio[0x4a:4]==0x13223344";
1188 break;
1189
1190 case DLT_IEEE802_11_RADIO:
1191 printf("DLT_IEEE802_11_RADIO Encap\n");
1192 nCaptureHeaderLength = 0x40;
1193 n80211HeaderLength = 0x18; // ieee80211 comes after this
1194 szProgram = "ether[0x0a:4]==0x13223344";
1195 break;
1196
1197 default:
1198 printf("!!! unknown encapsulation on %s !\n", argv[1]);
1199 return (1);
1200
1201 }
1202
1203 if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
1204 puts(szProgram);
1205 puts(pcap_geterr(ppcap));
1206 return (1);
1207 } else {
1208 if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
1209 puts(szProgram);
1210 puts(pcap_geterr(ppcap));
1211 } else {
1212 printf("RX Filter applied\n");
1213 }
1214 pcap_freecode(&bpfprogram);
1215 }
1216
1217 pcap_setnonblock(ppcap, 1, szErrbuf);
1218
1219 printf(" (delay between packets %dus)\n", nDelay);
1220
1221 memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
1222
1223 while (!fBrokenSocket) {
1224 u8 * pu8 = u8aSendBuffer;
1225 struct pcap_pkthdr * ppcapPacketHeader = NULL;
1226 struct ieee80211_radiotap_iterator rti;
1227 PENUMBRA_RADIOTAP_DATA prd;
1228 //init of the values
1229 prd.m_nRate = 255;
1230 prd.m_nChannel = 255;
1231 prd.m_nAntenna = 255;
1232 prd.m_nRadiotapFlags = 255;
1233 u8 * pu8Payload = u8aSendBuffer;
1234 int n, nRate;
1235
1236 // receive
1237
1238 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1239 (const u_char**)&pu8Payload);
1240
1241 if (retval < 0) {
1242 fBrokenSocket = 1;
1243 continue;
1244 }
1245
1246 if (retval != 1)
1247 goto do_tx;
1248
1249 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1250
1251 printf("rtap: ");
1252 Dump(pu8Payload, u16HeaderLen);
1253
1254 if (ppcapPacketHeader->len <
1255 (u16HeaderLen + n80211HeaderLength))
1256 continue;
1257
1258 bytes = ppcapPacketHeader->len -
1259 (u16HeaderLen + n80211HeaderLength);
1260 if (bytes < 0)
1261 continue;
1262
1263 if (ieee80211_radiotap_iterator_init(&rti,
1264 (struct ieee80211_radiotap_header *)pu8Payload,
1265 bytes) < 0)
1266 continue;
1267
1268 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
1269
1270 switch (rti.this_arg_index) {
1271 case IEEE80211_RADIOTAP_RATE:
1272 prd.m_nRate = (*rti.this_arg);
1273 break;
1274
1275 case IEEE80211_RADIOTAP_CHANNEL:
1276 prd.m_nChannel =
1277 le16_to_cpu(*((u16 *)rti.this_arg));
1278 prd.m_nChannelFlags =
1279 le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1280 break;
1281
1282 case IEEE80211_RADIOTAP_ANTENNA:
1283 prd.m_nAntenna = (*rti.this_arg) + 1;
1284 break;
1285
1286 case IEEE80211_RADIOTAP_FLAGS:
1287 prd.m_nRadiotapFlags = *rti.this_arg;
1288 break;
1289
1290 }
1291 }
1292
1293 pu8Payload += u16HeaderLen + n80211HeaderLength;
1294
1295 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1296 bytes -= 4;
1297
1298 printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1299 "Ant: %d, Flags: 0x%X\n",
1300 prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1301 prd.m_nChannel / 1000,
1302 prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
1303 prd.m_nAntenna,
1304 prd.m_nRadiotapFlags);
1305
1306 Dump(pu8Payload, bytes);
1307
1308 do_tx:
1309
1310 // transmit
1311
1312 memcpy(u8aSendBuffer, u8aRadiotapHeader,
1313 sizeof (u8aRadiotapHeader));
1314 if (flagMarkWithFCS)
1315 pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1316 nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1317 if (nRateIndex >= sizeof (u8aRatesToUse))
1318 nRateIndex = 0;
1319 pu8 += sizeof (u8aRadiotapHeader);
1320
1321 memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
1322 pu8 += sizeof (u8aIeeeHeader);
1323
1324 pu8 += sprintf((char *)u8aSendBuffer,
1325 "Packetspammer %02d"
1326 "broadcast packet"
1327 "#%05d -- :-D --%s ----",
1328 nRate/2, nOrdinal++, szHostname);
1329 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1330 if (r != (pu8-u8aSendBuffer)) {
1331 perror("Trouble injecting packet");
1332 return (1);
1333 }
1334 if (nDelay)
1335 usleep(nDelay);
1336 }
1337 1266
1267 // open the interface in pcap
1268
1269 szErrbuf[0] = '\0';
1270 ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1271 if (ppcap == NULL)
1272 {
1273 printf("Unable to open interface %s in pcap: %s\n",
1274 argv[optind], szErrbuf);
1275 return (1);
1276 }
1277
1278 //get mac from interface
1279
1280 /*int sock, j, k;
1281 char mac[32];
1282
1283 sock=socket(PF_INET, SOCK_STREAM, 0);
1284 if (-1==sock) {
1285 perror("can not open socket\n");
1286 return 1;
1287 }
1288
1289 if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1290 perror("ioctl(SIOCGIFHWADDR) ");
1291 return 1;
1292 }
1293 for (j=0, k=0; j<6; j++) {
1294 k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
1295 (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
1296 }
1297 mac[sizeof(mac)-1]='\0';
1298 */
1299
1300 //get header type
1301 nLinkEncap = pcap_datalink(ppcap);
1302 nCaptureHeaderLength = 0;
1303
1304 switch (nLinkEncap)
1305 {
1306
1307 case DLT_PRISM_HEADER:
1308 printf("DLT_PRISM_HEADER Encap\n");
1309 nCaptureHeaderLength = 0x40;
1310 n80211HeaderLength = 0x20; // ieee80211 comes after this
1311 szProgram = "radio[0x4a:4]==0x13223344";
1312 break;
1313
1314 case DLT_IEEE802_11_RADIO:
1315 printf("DLT_IEEE802_11_RADIO Encap\n");
1316 nCaptureHeaderLength = 0x40;
1317 n80211HeaderLength = 0x18; // ieee80211 comes after this
1318 szProgram = "ether[0x0a:4]==0x13223344";
1319 break;
1320
1321 default:
1322 printf("!!! unknown encapsulation on %s !\n", argv[1]);
1323 return (1);
1324
1325 }
1326
1327 if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1)
1328 {
1329 puts(szProgram);
1330 puts(pcap_geterr(ppcap));
1331 return (1);
1332 }
1333 else
1334 {
1335 if (pcap_setfilter(ppcap, &bpfprogram) == -1)
1336 {
1337 puts(szProgram);
1338 puts(pcap_geterr(ppcap));
1339 }
1340 else
1341 {
1342 printf("RX Filter applied\n");
1343 }
1344 pcap_freecode(&bpfprogram);
1345 }
1346
1347 pcap_setnonblock(ppcap, 1, szErrbuf);
1348
1349 printf(" (delay between packets %dus)\n", nDelay);
1350
1351 memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer));
1352
1353 while (!fBrokenSocket)
1354 {
1355 u8 * pu8 = u8aSendBuffer;
1356 struct pcap_pkthdr * ppcapPacketHeader = NULL;
1357 struct ieee80211_radiotap_iterator rti;
1358 PENUMBRA_RADIOTAP_DATA prd;
1359 //init of the values
1360 prd.m_nRate = 255;
1361 prd.m_nChannel = 255;
1362 prd.m_nAntenna = 255;
1363 prd.m_nRadiotapFlags = 255;
1364 u8 * pu8Payload = u8aSendBuffer;
1365 int n, nRate;
1366
1367 // receive
1368
1369 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1370 (const u_char**) &pu8Payload);
1371
1372 if (retval < 0)
1373 {
1374 fBrokenSocket = 1;
1375 continue;
1376 }
1377
1378 if (retval != 1)
1379 goto do_tx;
1380
1381 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1382
1383 printf("rtap: ");
1384 Dump(pu8Payload, u16HeaderLen);
1385
1386 if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength))
1387 continue;
1388
1389 bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength);
1390 if (bytes < 0)
1391 continue;
1392
1393 if (ieee80211_radiotap_iterator_init(&rti,
1394 (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0)
1395 continue;
1396
1397 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0)
1398 {
1399
1400 switch (rti.this_arg_index)
1401 {
1402 case IEEE80211_RADIOTAP_RATE:
1403 prd.m_nRate = (*rti.this_arg);
1404 break;
1405
1406 case IEEE80211_RADIOTAP_CHANNEL:
1407 prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg));
1408 prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1409 break;
1410
1411 case IEEE80211_RADIOTAP_ANTENNA:
1412 prd.m_nAntenna = (*rti.this_arg) + 1;
1413 break;
1414
1415 case IEEE80211_RADIOTAP_FLAGS:
1416 prd.m_nRadiotapFlags = *rti.this_arg;
1417 break;
1418
1419 }
1420 }
1421
1422 pu8Payload += u16HeaderLen + n80211HeaderLength;
1423
1424 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1425 bytes -= 4;
1426
1427 printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1428 "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1429 prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000)
1430 * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags);
1431
1432 Dump(pu8Payload, bytes);
1433
1434 do_tx:
1435
1436 // transmit
1437
1438 memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader));
1439 if (flagMarkWithFCS)
1440 pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1441 nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1442 if (nRateIndex >= sizeof(u8aRatesToUse))
1443 nRateIndex = 0;
1444 pu8 += sizeof(u8aRadiotapHeader);
1445
1446 memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader));
1447 pu8 += sizeof(u8aIeeeHeader);
1448
1449 pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d"
1450 "broadcast packet"
1451 "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname);
1452 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1453 if (r != (pu8 - u8aSendBuffer))
1454 {
1455 perror("Trouble injecting packet");
1456 return (1);
1457 }
1458 if (nDelay)
1459 usleep(nDelay);
1460 }
1338 1461
1339#endif 1462#endif
1340 return (0); 1463 return (0);
1341} 1464}
1342 1465