diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-04-20 10:31:00 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-04-20 10:31:00 +0000 |
commit | 4aa206ab8b98f140eb82bf2e4c9b832a2a63a262 (patch) | |
tree | a3764583e0cdd22aa80bfbd136276813c226ac0a /src/transport | |
parent | 27dd5c938cbda4224198d6faa93d652c63cf66f9 (diff) | |
download | gnunet-4aa206ab8b98f140eb82bf2e4c9b832a2a63a262.tar.gz gnunet-4aa206ab8b98f140eb82bf2e4c9b832a2a63a262.zip |
misc improvements
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-transport-wlan-helper.c | 1115 | ||||
-rw-r--r-- | src/transport/wlan/loopback_helper.c | 4 |
2 files changed, 509 insertions, 610 deletions
diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 7bfcf93ee..9759db532 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c | |||
@@ -28,6 +28,7 @@ | |||
28 | * gnunet | 28 | * gnunet |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #define _GNU_SOURCE | ||
31 | #include <sys/socket.h> | 32 | #include <sys/socket.h> |
32 | #include <sys/ioctl.h> | 33 | #include <sys/ioctl.h> |
33 | #include <sys/types.h> | 34 | #include <sys/types.h> |
@@ -45,7 +46,6 @@ | |||
45 | #include <stdlib.h> | 46 | #include <stdlib.h> |
46 | #include <string.h> | 47 | #include <string.h> |
47 | #include <stdarg.h> | 48 | #include <stdarg.h> |
48 | #include <unistd.h> | ||
49 | #include <fcntl.h> | 49 | #include <fcntl.h> |
50 | #include <errno.h> | 50 | #include <errno.h> |
51 | #include <dirent.h> | 51 | #include <dirent.h> |
@@ -56,7 +56,6 @@ | |||
56 | //#include <resolv.h> | 56 | //#include <resolv.h> |
57 | #include <string.h> | 57 | #include <string.h> |
58 | #include <utime.h> | 58 | #include <utime.h> |
59 | //#include <unistd.h> | ||
60 | #include <getopt.h> | 59 | #include <getopt.h> |
61 | */ | 60 | */ |
62 | //#include "platform.h" | 61 | //#include "platform.h" |
@@ -70,11 +69,6 @@ | |||
70 | #include "gnunet-transport-wlan-helper.h" | 69 | #include "gnunet-transport-wlan-helper.h" |
71 | #include "gnunet_crypto_lib.h" | 70 | #include "gnunet_crypto_lib.h" |
72 | 71 | ||
73 | #include <pcap.h> | ||
74 | #include <stdio.h> | ||
75 | #include <stdlib.h> | ||
76 | #include <sys/stat.h> | ||
77 | |||
78 | #include "wlan/radiotap-parser.h" | 72 | #include "wlan/radiotap-parser.h" |
79 | /* radiotap-parser defines types like u8 that | 73 | /* radiotap-parser defines types like u8 that |
80 | * ieee80211_radiotap.h needs | 74 | * ieee80211_radiotap.h needs |
@@ -93,42 +87,30 @@ | |||
93 | #define ARPHRD_IEEE80211_PRISM 802 | 87 | #define ARPHRD_IEEE80211_PRISM 802 |
94 | #define ARPHRD_IEEE80211_FULL 803 | 88 | #define ARPHRD_IEEE80211_FULL 803 |
95 | 89 | ||
96 | int closeprog; | ||
97 | |||
98 | #include "wlan/helper_common.h" | ||
99 | #include "wlan/loopback_helper.h" | 90 | #include "wlan/loopback_helper.h" |
100 | 91 | ||
101 | #define DEBUG 1 | 92 | #define DEBUG 1 |
102 | 93 | ||
94 | #define MAC_ADDR_SIZE 6 | ||
95 | |||
103 | struct Hardware_Infos | 96 | struct Hardware_Infos |
104 | { | 97 | { |
105 | 98 | ||
106 | struct sendbuf *write_pout; | 99 | struct sendbuf write_pout; |
107 | int fd_in, arptype_in; | 100 | int fd_raw; |
108 | int fd_out; | 101 | int arptype_in; |
109 | 102 | ||
110 | char *iface; | 103 | /** |
111 | unsigned char pl_mac[6]; | 104 | * Name of the interface, not necessarily 0-terminated (!). |
105 | */ | ||
106 | char iface[IFNAMSIZ]; | ||
107 | unsigned char pl_mac[MAC_ADDR_SIZE]; | ||
112 | }; | 108 | }; |
113 | 109 | ||
110 | // FIXME: inline? | ||
111 | int getChannelFromFrequency(int frequency); | ||
114 | 112 | ||
115 | 113 | // FIXME: make nice... | |
116 | static void | ||
117 | sigfunc_hw(int sig) | ||
118 | { | ||
119 | closeprog = 1; | ||
120 | } | ||
121 | |||
122 | static void | ||
123 | usage() | ||
124 | { | ||
125 | printf("Usage: interface-name options\n" | ||
126 | "options: 0 = with hardware\n" | ||
127 | "1 = first loopback file\n" | ||
128 | "2 = second loopback file\n" | ||
129 | "\n"); | ||
130 | } | ||
131 | |||
132 | static unsigned long | 114 | static unsigned long |
133 | calc_crc_osdep(unsigned char * buf, int len) | 115 | calc_crc_osdep(unsigned char * buf, int len) |
134 | { | 116 | { |
@@ -142,6 +124,7 @@ calc_crc_osdep(unsigned char * buf, int len) | |||
142 | 124 | ||
143 | /* CRC checksum verification routine */ | 125 | /* CRC checksum verification routine */ |
144 | 126 | ||
127 | // FIXME: make nice... | ||
145 | static int | 128 | static int |
146 | check_crc_buf_osdep(unsigned char *buf, int len) | 129 | check_crc_buf_osdep(unsigned char *buf, int len) |
147 | { | 130 | { |
@@ -156,6 +139,8 @@ check_crc_buf_osdep(unsigned char *buf, int len) | |||
156 | >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); | 139 | >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); |
157 | } | 140 | } |
158 | 141 | ||
142 | |||
143 | // FIXME: make nice... | ||
159 | static int | 144 | static int |
160 | linux_get_channel(struct Hardware_Infos *dev) | 145 | linux_get_channel(struct Hardware_Infos *dev) |
161 | { | 146 | { |
@@ -167,7 +152,7 @@ linux_get_channel(struct Hardware_Infos *dev) | |||
167 | 152 | ||
168 | strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ ); | 153 | strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ ); |
169 | 154 | ||
170 | fd = dev->fd_in; | 155 | fd = dev->fd_raw; |
171 | if (0 > ioctl(fd, SIOCGIWFREQ, &wrq)) | 156 | if (0 > ioctl(fd, SIOCGIWFREQ, &wrq)) |
172 | return (-1); | 157 | return (-1); |
173 | 158 | ||
@@ -185,249 +170,202 @@ linux_get_channel(struct Hardware_Infos *dev) | |||
185 | return chan; | 170 | return chan; |
186 | } | 171 | } |
187 | 172 | ||
188 | static int | ||
189 | linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, | ||
190 | struct Radiotap_rx * ri) | ||
191 | { | ||
192 | unsigned char tmpbuf[4096 * 4]; | ||
193 | 173 | ||
194 | int caplen, n, got_signal, got_noise, got_channel, fcs_removed; | 174 | // FIXME: make nice... |
175 | static ssize_t | ||
176 | linux_read (struct Hardware_Infos *dev, | ||
177 | unsigned char *buf, /* FIXME: void*? */ | ||
178 | size_t buf_size, | ||
179 | struct Radiotap_rx *ri) | ||
180 | { | ||
181 | unsigned char tmpbuf[buf_size]; | ||
182 | ssize_t caplen; | ||
183 | int n, got_signal, got_noise, got_channel, fcs_removed; | ||
195 | 184 | ||
196 | caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0; | 185 | n = got_signal = got_noise = got_channel = fcs_removed = 0; |
197 | 186 | ||
198 | if ((unsigned) count > sizeof(tmpbuf)) | 187 | caplen = read(dev->fd_raw, tmpbuf, buf_size); |
199 | return (-1); | ||
200 | caplen = read(dev->fd_in, tmpbuf, count); | ||
201 | if (0 > caplen) | 188 | if (0 > caplen) |
202 | { | 189 | { |
203 | if (EAGAIN == errno) | 190 | if (EAGAIN == errno) |
204 | return (0); | 191 | return 0; |
205 | 192 | fprintf (stderr, | |
206 | perror("read failed"); | 193 | "Failed to read from RAW socket: %s\n", |
207 | return (-1); | 194 | strerror (errno)); |
195 | return -1; | ||
208 | } | 196 | } |
209 | 197 | ||
210 | memset(buf, 0, sizeof(buf)); | 198 | memset(buf, 0, buf_size); |
211 | 199 | memset(ri, 0, sizeof(*ri)); | |
212 | if (ri) | ||
213 | memset(ri, 0, sizeof(*ri)); | ||
214 | 200 | ||
215 | if (ARPHRD_IEEE80211_PRISM == dev->arptype_in ) | 201 | switch (dev->arptype_in) |
216 | { | 202 | { |
217 | /* skip the prism header */ | 203 | case ARPHRD_IEEE80211_PRISM: |
218 | if (tmpbuf[7] == 0x40) | 204 | { |
219 | { | 205 | /* skip the prism header */ |
220 | /* prism54 uses a different format */ | 206 | if (tmpbuf[7] == 0x40) |
221 | if (ri) | 207 | { |
222 | { | 208 | /* prism54 uses a different format */ |
223 | ri->ri_power = tmpbuf[0x33]; | 209 | ri->ri_power = tmpbuf[0x33]; |
224 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); | 210 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); |
225 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; | 211 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; |
226 | 212 | got_signal = 1; | |
227 | got_signal = 1; | 213 | got_noise = 1; |
228 | got_noise = 1; | 214 | n = 0x40; |
229 | } | 215 | } |
230 | 216 | else | |
231 | n = 0x40; | 217 | { |
232 | } | 218 | ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48); |
233 | else | 219 | ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); |
234 | { | 220 | ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); |
235 | if (ri) | 221 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); |
236 | { | 222 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; |
237 | ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48); | 223 | got_channel = 1; |
238 | ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); | 224 | got_signal = 1; |
239 | ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); | 225 | got_noise = 1; |
240 | ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); | 226 | n = *(int *) (tmpbuf + 4); |
241 | ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; | 227 | } |
242 | 228 | ||
243 | got_channel = 1; | 229 | if (n < 8 || n >= caplen) |
244 | got_signal = 1; | 230 | return (0); |
245 | got_noise = 1; | 231 | } |
246 | } | 232 | break; |
247 | 233 | ||
248 | n = *(int *) (tmpbuf + 4); | 234 | case ARPHRD_IEEE80211_FULL: |
249 | } | 235 | { |
250 | 236 | struct ieee80211_radiotap_iterator iterator; | |
251 | if (n < 8 || n >= caplen) | 237 | struct ieee80211_radiotap_header *rthdr; |
252 | return (0); | 238 | |
253 | } | 239 | rthdr = (struct ieee80211_radiotap_header *) tmpbuf; |
254 | 240 | ||
255 | if (ARPHRD_IEEE80211_FULL == dev->arptype_in) | 241 | if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0) |
256 | { | 242 | return (0); |
257 | struct ieee80211_radiotap_iterator iterator; | 243 | |
258 | struct ieee80211_radiotap_header *rthdr; | 244 | /* go through the radiotap arguments we have been given |
259 | 245 | * by the driver | |
260 | rthdr = (struct ieee80211_radiotap_header *) tmpbuf; | 246 | */ |
261 | 247 | ||
262 | if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0) | 248 | while (ieee80211_radiotap_iterator_next(&iterator) >= 0) |
263 | return (0); | 249 | { |
264 | 250 | ||
265 | /* go through the radiotap arguments we have been given | 251 | switch (iterator.this_arg_index) |
266 | * by the driver | 252 | { |
267 | */ | 253 | |
268 | 254 | case IEEE80211_RADIOTAP_TSFT: | |
269 | while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0)) | 255 | ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg)); |
270 | { | 256 | break; |
271 | 257 | ||
272 | switch (iterator.this_arg_index) | 258 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: |
273 | { | 259 | if (!got_signal) |
274 | 260 | { | |
275 | case IEEE80211_RADIOTAP_TSFT: | 261 | if (*iterator.this_arg < 127) |
276 | ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg)); | 262 | ri->ri_power = *iterator.this_arg; |
277 | break; | 263 | else |
278 | 264 | ri->ri_power = *iterator.this_arg - 255; | |
279 | case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: | 265 | |
280 | if (!got_signal) | 266 | got_signal = 1; |
281 | { | 267 | } |
282 | if (*iterator.this_arg < 127) | 268 | break; |
283 | ri->ri_power = *iterator.this_arg; | 269 | |
284 | else | 270 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: |
285 | ri->ri_power = *iterator.this_arg - 255; | 271 | if (!got_signal) |
286 | 272 | { | |
287 | got_signal = 1; | 273 | if (*iterator.this_arg < 127) |
288 | } | 274 | ri->ri_power = *iterator.this_arg; |
289 | break; | 275 | else |
290 | 276 | ri->ri_power = *iterator.this_arg - 255; | |
291 | case IEEE80211_RADIOTAP_DB_ANTSIGNAL: | 277 | |
292 | if (!got_signal) | 278 | got_signal = 1; |
293 | { | 279 | } |
294 | if (*iterator.this_arg < 127) | 280 | break; |
295 | ri->ri_power = *iterator.this_arg; | 281 | |
296 | else | 282 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: |
297 | ri->ri_power = *iterator.this_arg - 255; | 283 | if (!got_noise) |
298 | 284 | { | |
299 | got_signal = 1; | 285 | if (*iterator.this_arg < 127) |
300 | } | 286 | ri->ri_noise = *iterator.this_arg; |
301 | break; | 287 | else |
302 | 288 | ri->ri_noise = *iterator.this_arg - 255; | |
303 | case IEEE80211_RADIOTAP_DBM_ANTNOISE: | 289 | |
304 | if (!got_noise) | 290 | got_noise = 1; |
305 | { | 291 | } |
306 | if (*iterator.this_arg < 127) | 292 | break; |
307 | ri->ri_noise = *iterator.this_arg; | 293 | |
308 | else | 294 | case IEEE80211_RADIOTAP_DB_ANTNOISE: |
309 | ri->ri_noise = *iterator.this_arg - 255; | 295 | if (!got_noise) |
310 | 296 | { | |
311 | got_noise = 1; | 297 | if (*iterator.this_arg < 127) |
312 | } | 298 | ri->ri_noise = *iterator.this_arg; |
313 | break; | 299 | else |
314 | 300 | ri->ri_noise = *iterator.this_arg - 255; | |
315 | case IEEE80211_RADIOTAP_DB_ANTNOISE: | 301 | |
316 | if (!got_noise) | 302 | got_noise = 1; |
317 | { | 303 | } |
318 | if (*iterator.this_arg < 127) | 304 | break; |
319 | ri->ri_noise = *iterator.this_arg; | 305 | |
320 | else | 306 | case IEEE80211_RADIOTAP_ANTENNA: |
321 | ri->ri_noise = *iterator.this_arg - 255; | 307 | ri->ri_antenna = *iterator.this_arg; |
322 | 308 | break; | |
323 | got_noise = 1; | 309 | |
324 | } | 310 | case IEEE80211_RADIOTAP_CHANNEL: |
325 | break; | 311 | ri->ri_channel = *iterator.this_arg; |
326 | 312 | got_channel = 1; | |
327 | case IEEE80211_RADIOTAP_ANTENNA: | 313 | break; |
328 | ri->ri_antenna = *iterator.this_arg; | 314 | |
329 | break; | 315 | case IEEE80211_RADIOTAP_RATE: |
330 | 316 | ri->ri_rate = (*iterator.this_arg) * 500000; | |
331 | case IEEE80211_RADIOTAP_CHANNEL: | 317 | break; |
332 | ri->ri_channel = *iterator.this_arg; | 318 | |
333 | got_channel = 1; | 319 | case IEEE80211_RADIOTAP_FLAGS: |
334 | break; | 320 | /* is the CRC visible at the end? |
335 | 321 | * remove | |
336 | case IEEE80211_RADIOTAP_RATE: | 322 | */ |
337 | ri->ri_rate = (*iterator.this_arg) * 500000; | 323 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) |
338 | break; | 324 | { |
339 | 325 | fcs_removed = 1; | |
340 | case IEEE80211_RADIOTAP_FLAGS: | 326 | caplen -= 4; |
341 | /* is the CRC visible at the end? | 327 | } |
342 | * remove | 328 | |
343 | */ | 329 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) |
344 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) | 330 | return (0); |
345 | { | 331 | |
346 | fcs_removed = 1; | 332 | break; |
347 | caplen -= 4; | 333 | } |
348 | } | 334 | } |
349 | 335 | n = le16_to_cpu(rthdr->it_len); | |
350 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) | 336 | if (n <= 0 || n >= caplen) |
351 | return (0); | 337 | return 0; |
352 | 338 | } | |
353 | break; | 339 | break; |
354 | 340 | case ARPHRD_IEEE80211: | |
355 | } | 341 | /* do nothing? */ |
356 | } | 342 | break; |
357 | 343 | default: | |
358 | n = le16_to_cpu(rthdr->it_len); | 344 | errno = ENOTSUP; |
359 | 345 | return -1; | |
360 | if (n <= 0 || n >= caplen) | ||
361 | return (0); | ||
362 | } | 346 | } |
363 | 347 | ||
364 | caplen -= n; | 348 | caplen -= n; |
365 | 349 | ||
366 | //detect fcs at the end, even if the flag wasn't set and remove it | 350 | //detect fcs at the end, even if the flag wasn't set and remove it |
367 | if (0 == fcs_removed && 1== check_crc_buf_osdep(tmpbuf + n, caplen - 4)) | 351 | if ( (0 == fcs_removed) && |
352 | (1 == check_crc_buf_osdep(tmpbuf + n, caplen - 4)) ) | ||
368 | { | 353 | { |
369 | caplen -= 4; | 354 | caplen -= 4; |
370 | } | 355 | } |
371 | |||
372 | memcpy(buf, tmpbuf + n, caplen); | 356 | memcpy(buf, tmpbuf + n, caplen); |
373 | 357 | if (! got_channel) | |
374 | if (ri && !got_channel) | ||
375 | ri->ri_channel = linux_get_channel(dev); | 358 | ri->ri_channel = linux_get_channel(dev); |
376 | 359 | ||
377 | return (caplen); | 360 | return caplen; |
378 | } | 361 | } |
379 | 362 | ||
380 | static int | ||
381 | linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count) | ||
382 | { | ||
383 | int ret; | ||
384 | //int usedrtap; | ||
385 | //unsigned short int *p_rtlen; | ||
386 | |||
387 | //unsigned char * u8aRadiotap = buf; | ||
388 | |||
389 | /* Pointer to the radiotap header length field for later use. */ | ||
390 | //p_rtlen = (unsigned short int*) (u8aRadiotap + 2); | ||
391 | //usedrtap = 0; | ||
392 | ret = write(dev->fd_out, buf, count); | ||
393 | |||
394 | if (0 > ret) | ||
395 | { | ||
396 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno | ||
397 | == ENOMEM) | ||
398 | { | ||
399 | usleep(10000); | ||
400 | return (0); | ||
401 | } | ||
402 | |||
403 | perror("write failed"); | ||
404 | return (-1); | ||
405 | } | ||
406 | |||
407 | /* radiotap header length is stored little endian on all systems */ | ||
408 | /*if (usedrtap) | ||
409 | ret -= letoh16(*p_rtlen); | ||
410 | |||
411 | if (0 > ret) | ||
412 | { | ||
413 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno | ||
414 | == ENOMEM) | ||
415 | { | ||
416 | usleep(10000); | ||
417 | return (0); | ||
418 | } | ||
419 | |||
420 | perror("write failed"); | ||
421 | return (-1); | ||
422 | }*/ | ||
423 | |||
424 | return (ret); | ||
425 | } | ||
426 | 363 | ||
364 | /** | ||
365 | * @return 0 on success | ||
366 | */ | ||
427 | static int | 367 | static int |
428 | openraw(struct Hardware_Infos * dev, | 368 | openraw (struct Hardware_Infos *dev) |
429 | const char * iface, int fd, int * arptype, | ||
430 | uint8_t *mac) | ||
431 | { | 369 | { |
432 | struct ifreq ifr; | 370 | struct ifreq ifr; |
433 | struct iwreq wrq; | 371 | struct iwreq wrq; |
@@ -435,49 +373,53 @@ openraw(struct Hardware_Infos * dev, | |||
435 | struct sockaddr_ll sll; | 373 | struct sockaddr_ll sll; |
436 | 374 | ||
437 | /* find the interface index */ | 375 | /* find the interface index */ |
438 | |||
439 | memset(&ifr, 0, sizeof(ifr)); | 376 | memset(&ifr, 0, sizeof(ifr)); |
440 | strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); | 377 | strncpy(ifr.ifr_name, dev->iface, IFNAMSIZ); |
441 | 378 | if (-1 == ioctl(dev->fd_raw, SIOCGIFINDEX, &ifr)) | |
442 | if (0 > ioctl(fd, SIOCGIFINDEX, &ifr)) | ||
443 | { | 379 | { |
444 | printf("Interface %s: \n", iface); | 380 | fprintf (stderr, |
445 | perror("ioctl(SIOCGIFINDEX) failed"); | 381 | "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", |
446 | return (1); | 382 | IFNAMSIZ, |
383 | dev->iface, | ||
384 | strerror (errno)); | ||
385 | return 1; | ||
447 | } | 386 | } |
448 | 387 | ||
449 | memset(&sll, 0, sizeof(sll)); | 388 | /* lookup the hardware type */ |
389 | memset (&sll, 0, sizeof(sll)); | ||
450 | sll.sll_family = AF_PACKET; | 390 | sll.sll_family = AF_PACKET; |
451 | sll.sll_ifindex = ifr.ifr_ifindex; | 391 | sll.sll_ifindex = ifr.ifr_ifindex; |
452 | |||
453 | sll.sll_protocol = htons(ETH_P_ALL); | 392 | sll.sll_protocol = htons(ETH_P_ALL); |
454 | 393 | if (-1 == ioctl(dev->fd_raw, SIOCGIFHWADDR, &ifr)) | |
455 | /* lookup the hardware type */ | ||
456 | |||
457 | if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) | ||
458 | { | 394 | { |
459 | printf("Interface %s: \n", iface); | 395 | fprintf (stderr, |
460 | perror("ioctl(SIOCGIFHWADDR) failed"); | 396 | "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", |
461 | return (1); | 397 | IFNAMSIZ, |
398 | dev->iface, | ||
399 | strerror (errno)); | ||
400 | return 1; | ||
462 | } | 401 | } |
463 | 402 | ||
464 | /* lookup iw mode */ | 403 | /* lookup iw mode */ |
465 | memset(&wrq, 0, sizeof(struct iwreq)); | 404 | memset(&wrq, 0, sizeof(struct iwreq)); |
466 | strncpy(wrq.ifr_name, iface, IFNAMSIZ); | 405 | strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ); |
467 | 406 | if (-1 == ioctl(dev->fd_raw, SIOCGIWMODE, &wrq)) | |
468 | if (0 > ioctl(fd, SIOCGIWMODE, &wrq)) | ||
469 | { | 407 | { |
470 | /* most probably not supported (ie for rtap ipw interface) * | 408 | /* most probably not supported (ie for rtap ipw interface) * |
471 | * so just assume its correctly set... */ | 409 | * so just assume its correctly set... */ |
472 | wrq.u.mode = IW_MODE_MONITOR; | 410 | wrq.u.mode = IW_MODE_MONITOR; |
473 | } | 411 | } |
474 | 412 | ||
475 | if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family | 413 | if ( ( (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && |
476 | != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family | 414 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && |
477 | != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR)) | 415 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL) ) || |
416 | (wrq.u.mode != IW_MODE_MONITOR) ) | ||
478 | { | 417 | { |
479 | printf("Error: %s not in monitor mode\n", iface); | 418 | fprintf (stderr, |
480 | return (1); | 419 | "Error: interface `%.*s' is not in monitor mode\n", |
420 | IFNAMSIZ, | ||
421 | dev->iface); | ||
422 | return 1; | ||
481 | } | 423 | } |
482 | 424 | ||
483 | /* Is interface st to up, broadcast & running ? */ | 425 | /* Is interface st to up, broadcast & running ? */ |
@@ -486,91 +428,99 @@ openraw(struct Hardware_Infos * dev, | |||
486 | /* Bring interface up*/ | 428 | /* Bring interface up*/ |
487 | ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; | 429 | ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; |
488 | 430 | ||
489 | if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) | 431 | if (-1 != ioctl(dev->fd_raw, SIOCSIFFLAGS, &ifr)) |
490 | { | 432 | { |
491 | perror("ioctl(SIOCSIFFLAGS) failed"); | 433 | fprintf (stderr, |
492 | return (1); | 434 | "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", |
435 | IFNAMSIZ, | ||
436 | dev->iface, | ||
437 | strerror (errno)); | ||
438 | return 1; | ||
493 | } | 439 | } |
494 | } | 440 | } |
495 | /* bind the raw socket to the interface */ | ||
496 | 441 | ||
497 | if (0 > bind(fd, (struct sockaddr *) &sll, sizeof(sll))) | 442 | /* bind the raw socket to the interface */ |
443 | if (-1 == bind(dev->fd_raw, (struct sockaddr *) &sll, sizeof(sll))) | ||
498 | { | 444 | { |
499 | printf("Interface %s: \n", iface); | 445 | fprintf (stderr, |
500 | perror("bind(ETH_P_ALL) failed"); | 446 | "Failed to bind interface `%.*s': %s\n", |
501 | return (1); | 447 | IFNAMSIZ, |
448 | dev->iface, | ||
449 | strerror (errno)); | ||
450 | return 1; | ||
502 | } | 451 | } |
503 | 452 | ||
504 | /* lookup the hardware type */ | 453 | /* lookup the hardware type */ |
505 | 454 | if (-1 != ioctl(dev->fd_raw, SIOCGIFHWADDR, &ifr)) | |
506 | if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) | ||
507 | { | 455 | { |
508 | printf("Interface %s: \n", iface); | 456 | fprintf (stderr, |
509 | perror("ioctl(SIOCGIFHWADDR) failed"); | 457 | "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", |
510 | return (1); | 458 | IFNAMSIZ, |
459 | dev->iface, | ||
460 | strerror (errno)); | ||
461 | return 1; | ||
511 | } | 462 | } |
512 | 463 | ||
513 | memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6); | 464 | memcpy (dev->pl_mac, |
514 | 465 | ifr.ifr_hwaddr.sa_data, | |
515 | *arptype = ifr.ifr_hwaddr.sa_family; | 466 | MAC_ADDR_SIZE); |
516 | 467 | dev->arptype_in = ifr.ifr_hwaddr.sa_family; | |
517 | if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family | 468 | if ( (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && |
518 | != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family | 469 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && |
519 | != ARPHRD_IEEE80211_FULL) | 470 | (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL) ) |
520 | { | 471 | { |
521 | if (1 == ifr.ifr_hwaddr.sa_family) | 472 | fprintf (stderr, |
522 | fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) "); | 473 | "Unsupported hardware link type %d on interface `%.*s'\n", |
523 | else | 474 | ifr.ifr_hwaddr.sa_family, |
524 | fprintf(stderr, "\nUnsupported hardware link type %4d ", | 475 | IFNAMSIZ, |
525 | ifr.ifr_hwaddr.sa_family); | 476 | dev->iface); |
526 | 477 | return 1; | |
527 | fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_" | ||
528 | "FULL or ARPHRD_IEEE80211_PRISM instead. Make\n" | ||
529 | "sure RFMON is enabled: run 'airmon-ng start %s" | ||
530 | " <#>'\nSysfs injection support was not found " | ||
531 | "either.\n\n", iface); | ||
532 | return (1); | ||
533 | } | 478 | } |
534 | 479 | ||
535 | /* enable promiscuous mode */ | 480 | /* enable promiscuous mode */ |
536 | |||
537 | memset(&mr, 0, sizeof(mr)); | 481 | memset(&mr, 0, sizeof(mr)); |
538 | mr.mr_ifindex = sll.sll_ifindex; | 482 | mr.mr_ifindex = sll.sll_ifindex; |
539 | mr.mr_type = PACKET_MR_PROMISC; | 483 | mr.mr_type = PACKET_MR_PROMISC; |
540 | 484 | if (0 != setsockopt(dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr))) | |
541 | if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) | ||
542 | { | 485 | { |
543 | perror("setsockopt(PACKET_MR_PROMISC) failed"); | 486 | fprintf (stderr, |
544 | return (1); | 487 | "Failed to enable promiscuous mode on interface `%.*s'\n", |
488 | IFNAMSIZ, | ||
489 | dev->iface); | ||
490 | return 1; | ||
545 | } | 491 | } |
546 | 492 | ||
547 | return (0); | 493 | return 0; |
548 | } | 494 | } |
549 | 495 | ||
496 | /** | ||
497 | * @return 0 on success | ||
498 | */ | ||
550 | static int | 499 | static int |
551 | wlaninit(struct Hardware_Infos * dev, const char *iface) | 500 | wlaninit (struct Hardware_Infos *dev, |
501 | const char *iface) | ||
552 | { | 502 | { |
553 | char strbuf[512]; | 503 | char strbuf[512]; |
554 | struct stat sbuf; | 504 | struct stat sbuf; |
555 | int ret; | 505 | int ret; |
556 | 506 | ||
557 | dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | 507 | dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); |
558 | if (0 > dev->fd_out) | 508 | if (0 > dev->fd_raw) |
559 | { | 509 | { |
560 | perror("socket(PF_PACKET) failed at fd_out"); | 510 | fprintf (stderr, |
561 | goto close_in; | 511 | "Failed to create raw socket: %s\n", |
512 | strerror (errno)); | ||
513 | return 1; | ||
514 | } | ||
515 | if (dev->fd_raw >= FD_SETSIZE) | ||
516 | { | ||
517 | fprintf (stderr, | ||
518 | "File descriptor too large for select (%d > %d)\n", | ||
519 | dev->fd_raw, | ||
520 | FD_SETSIZE); | ||
521 | close (dev->fd_raw); | ||
522 | return 1; | ||
562 | } | 523 | } |
563 | |||
564 | /* figure out device type */ | ||
565 | |||
566 | /* mac80211 radiotap injection | ||
567 | * detected based on interface called mon... | ||
568 | * since mac80211 allows multiple virtual interfaces | ||
569 | * | ||
570 | * note though that the virtual interfaces are ultimately using a | ||
571 | * single physical radio: that means for example they must all | ||
572 | * operate on the same channel | ||
573 | */ | ||
574 | 524 | ||
575 | /* mac80211 stack detection */ | 525 | /* mac80211 stack detection */ |
576 | ret = snprintf(strbuf, | 526 | ret = snprintf(strbuf, |
@@ -584,127 +534,115 @@ wlaninit(struct Hardware_Infos * dev, const char *iface) | |||
584 | fprintf(stderr, | 534 | fprintf(stderr, |
585 | "Did not find 802.11 interface `%s'. Exiting.\n", | 535 | "Did not find 802.11 interface `%s'. Exiting.\n", |
586 | iface); | 536 | iface); |
537 | close (dev->fd_raw); | ||
587 | return 1; | 538 | return 1; |
588 | } | 539 | } |
589 | 540 | strncpy(dev->iface, iface, IFNAMSIZ); | |
590 | if (openraw(dev, iface, dev->fd_out, &dev->arptype_in, dev->pl_mac) != 0) | 541 | if (0 != openraw(dev)) |
591 | { | 542 | { |
592 | goto close_out; | 543 | close(dev->fd_raw); |
544 | return 1; | ||
593 | } | 545 | } |
594 | |||
595 | dev->fd_in = dev->fd_out; | ||
596 | dev->iface = GNUNET_malloc(sizeof(char) *6); | ||
597 | strncpy(dev->iface, iface, sizeof(char) * 6); | ||
598 | |||
599 | |||
600 | return 0; | 546 | return 0; |
601 | close_out: close(dev->fd_out); | ||
602 | close_in: close(dev->fd_in); | ||
603 | return 1; | ||
604 | } | 547 | } |
605 | 548 | ||
549 | |||
606 | /** | 550 | /** |
607 | * function to test incoming packets mac | 551 | * Function to test incoming packets mac for being our own. |
608 | * @param buf buffer of the packet | 552 | * |
609 | * @param dev pointer to the Hardware_Infos struct | 553 | * @param u8aIeeeHeader buffer of the packet |
610 | * @return 0 if macs are okay, 1 if macs are wrong | 554 | * @param dev the Hardware_Infos struct |
555 | * @return 0 if mac belongs to us, 1 if mac is for another target | ||
611 | */ | 556 | */ |
612 | |||
613 | static int | 557 | static int |
614 | mac_test(unsigned char * buf, struct Hardware_Infos * dev) | 558 | mac_test (const struct ieee80211_frame *u8aIeeeHeader, |
559 | const struct Hardware_Infos *dev) | ||
615 | { | 560 | { |
616 | struct ieee80211_frame * u8aIeeeHeader; | 561 | if (0 != memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE)) |
617 | u8aIeeeHeader = (struct ieee80211_frame *) buf; | 562 | return 1; |
618 | if (0 == memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, 6)) | 563 | if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE)) |
619 | { | 564 | return 0; |
620 | if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, 6)) | 565 | if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE)) |
621 | { | 566 | return 0; |
622 | return 0; | ||
623 | } | ||
624 | |||
625 | if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, 6)) | ||
626 | { | ||
627 | return 0; | ||
628 | } | ||
629 | } | ||
630 | |||
631 | return 1; | 567 | return 1; |
632 | } | 568 | } |
633 | 569 | ||
570 | |||
634 | /** | 571 | /** |
635 | * function to set the wlan header to make attacks more difficult | 572 | * function to set the wlan header to make attacks more difficult |
636 | * @param buf buffer of the packet | 573 | * @param buf buffer of the packet |
637 | * @param dev pointer to the Hardware_Infos struct | 574 | * @param dev pointer to the Hardware_Infos struct |
638 | */ | 575 | */ |
639 | |||
640 | static void | 576 | static void |
641 | mac_set(unsigned char * buf, struct Hardware_Infos * dev) | 577 | mac_set (struct ieee80211_frame *u8aIeeeHeader, |
578 | const struct Hardware_Infos * dev) | ||
642 | { | 579 | { |
643 | struct ieee80211_frame * u8aIeeeHeader; | ||
644 | u8aIeeeHeader = (struct ieee80211_frame *) buf; | ||
645 | |||
646 | u8aIeeeHeader->i_fc[0] = 0x08; | 580 | u8aIeeeHeader->i_fc[0] = 0x08; |
647 | u8aIeeeHeader->i_fc[1] = 0x00; | 581 | u8aIeeeHeader->i_fc[1] = 0x00; |
648 | 582 | memcpy(u8aIeeeHeader->i_addr2, | |
649 | memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6); | 583 | dev->pl_mac, |
650 | memcpy(u8aIeeeHeader->i_addr3, &mac_bssid, 6); | 584 | MAC_ADDR_SIZE); |
585 | memcpy(u8aIeeeHeader->i_addr3, | ||
586 | &mac_bssid, | ||
587 | MAC_ADDR_SIZE); | ||
651 | 588 | ||
652 | } | 589 | } |
653 | 590 | ||
591 | |||
654 | static void | 592 | static void |
655 | stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) | 593 | stdin_send_hw (void *cls, |
594 | void *client, | ||
595 | const struct GNUNET_MessageHeader *hdr) | ||
656 | { | 596 | { |
657 | struct Hardware_Infos * dev = cls; | 597 | struct Hardware_Infos * dev = cls; |
658 | struct sendbuf *write_pout = dev->write_pout; | 598 | struct sendbuf *write_pout = &dev->write_pout; |
659 | struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1]; | 599 | struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1]; |
660 | unsigned char * wlanheader; | 600 | struct ieee80211_frame * wlanheader; |
661 | 601 | size_t sendsize; | |
662 | int sendsize; | ||
663 | 602 | ||
603 | // struct? // FIXME: make nice... | ||
664 | unsigned char u8aRadiotap[] = | 604 | unsigned char u8aRadiotap[] = |
665 | { 0x00, 0x00, // <-- radiotap version | 605 | { 0x00, 0x00, // <-- radiotap version |
666 | 0x0c, 0x00, // <- radiotap header length | 606 | 0x0c, 0x00, // <- radiotap header length |
667 | 0x04, 0x80, 0x00, 0x00, // <-- bitmap | 607 | 0x04, 0x80, 0x00, 0x00, // <-- bitmap |
668 | 0x00, // <-- rate | 608 | 0x00, // <-- rate |
669 | 0x00, // <-- padding for natural alignment | 609 | 0x00, // <-- padding for natural alignment |
670 | 0x18, 0x00, // <-- TX flags | 610 | 0x18, 0x00, // <-- TX flags |
671 | }; | 611 | }; |
672 | 612 | ||
673 | sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send) | 613 | sendsize = ntohs(hdr->size); |
674 | - sizeof(struct GNUNET_MessageHeader); | 614 | if (sendsize < sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader)) |
675 | |||
676 | if (MAXLINE * 2 < sendsize) | ||
677 | { | 615 | { |
678 | fprintf(stderr, "Function stdin_send: Packet too big for buffer\n"); | 616 | fprintf(stderr, |
679 | exit(1); | 617 | "Function stdin_send_hw: mailformed packet (too small)\n"); |
618 | exit (1); | ||
680 | } | 619 | } |
620 | sendsize -= sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader); | ||
681 | 621 | ||
682 | if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)) | 622 | if (MAXLINE < sendsize) |
683 | { | 623 | { |
684 | fprintf(stderr, "Function stdin_send: wrong packet type\n"); | 624 | fprintf(stderr, |
625 | "Function stdin_send_hw: Packet too big for buffer\n"); | ||
685 | exit(1); | 626 | exit(1); |
686 | } | 627 | } |
687 | 628 | if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)) | |
688 | if ( sizeof(struct ieee80211_frame) | ||
689 | + sizeof(struct GNUNET_MessageHeader) > sendsize) | ||
690 | { | 629 | { |
691 | fprintf(stderr, "Function stdin_send: packet too small\n"); | 630 | fprintf(stderr, "Function stdin_send: wrong packet type\n"); |
692 | exit(1); | 631 | exit(1); |
693 | } | 632 | } |
694 | 633 | ||
695 | u8aRadiotap[2] = htole16(sizeof(u8aRadiotap)); | 634 | u8aRadiotap[2] = htole16(sizeof(u8aRadiotap)); // WTF? |
696 | u8aRadiotap[8] = header->rate; | 635 | u8aRadiotap[8] = header->rate; |
697 | |||
698 | memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap)); | 636 | memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap)); |
699 | memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize); | 637 | memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize); |
700 | 638 | /* payload contains MAC address, but we don't trust it, so we'll | |
701 | wlanheader = write_pout->buf + sizeof(u8aRadiotap); | 639 | overwrite it with OUR MAC address again to prevent mischief */ |
640 | wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof(u8aRadiotap)); | ||
702 | mac_set(wlanheader, dev); | 641 | mac_set(wlanheader, dev); |
703 | 642 | write_pout->size = sendsize + sizeof(u8aRadiotap); | |
704 | sendsize += sizeof(u8aRadiotap); | ||
705 | write_pout->size = sendsize; | ||
706 | } | 643 | } |
707 | 644 | ||
645 | #if 0 | ||
708 | static int | 646 | static int |
709 | maketest(unsigned char * buf, struct Hardware_Infos * dev) | 647 | maketest(unsigned char * buf, struct Hardware_Infos * dev) |
710 | { | 648 | { |
@@ -762,7 +700,7 @@ maketest(unsigned char * buf, struct Hardware_Infos * dev) | |||
762 | if (0 == first) | 700 | if (0 == first) |
763 | { | 701 | { |
764 | memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame)); | 702 | memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame)); |
765 | memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6); | 703 | memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE); |
766 | first = 1; | 704 | first = 1; |
767 | } | 705 | } |
768 | 706 | ||
@@ -780,274 +718,231 @@ maketest(unsigned char * buf, struct Hardware_Infos * dev) | |||
780 | return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt); | 718 | return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt); |
781 | 719 | ||
782 | } | 720 | } |
721 | #endif | ||
783 | 722 | ||
784 | int | ||
785 | hardwaremode(int argc, char *argv[]) | ||
786 | { | ||
787 | |||
788 | uid_t uid; | ||
789 | struct Hardware_Infos dev; | ||
790 | struct Radiotap_rx * rxinfo; | ||
791 | uint8_t * mac = dev.pl_mac; | ||
792 | int fdpin, fdpout; | ||
793 | 723 | ||
794 | struct GNUNET_MessageHeader * header; | 724 | /** |
725 | * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin | ||
726 | * @param buffer pointer to buffer for the message | ||
727 | * @param mac pointer to the mac address | ||
728 | * @return number of bytes written | ||
729 | */ | ||
730 | // FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file) | ||
731 | static int | ||
732 | send_mac_to_plugin(char * buffer, uint8_t * mac) | ||
733 | { | ||
734 | struct Wlan_Helper_Control_Message macmsg; | ||
795 | 735 | ||
796 | signal(SIGINT, &sigfunc_hw); | 736 | macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message)); |
797 | signal(SIGTERM, &sigfunc_hw); | 737 | macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL); |
738 | memcpy(macmsg.mac.mac, mac, sizeof(struct MacAddress)); | ||
739 | memcpy(buffer, &macmsg, sizeof(struct Wlan_Helper_Control_Message)); | ||
740 | return sizeof(struct Wlan_Helper_Control_Message); | ||
741 | } | ||
798 | 742 | ||
799 | if (wlaninit(&dev, argv[1])) | ||
800 | { | ||
801 | return 1; | ||
802 | } | ||
803 | 743 | ||
804 | uid = getuid(); | 744 | static int |
805 | //if (0 != setresuid(uid, uid, uid)) | 745 | hardwaremode (int argc, |
806 | //{ | 746 | char *argv[]) |
807 | // fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno)); | 747 | { |
808 | /* not critical, continue anyway */ | 748 | uid_t uid; |
809 | //} | 749 | struct Hardware_Infos dev; |
810 | |||
811 | unsigned char * datastart; | ||
812 | char readbuf[MAXLINE]; | 750 | char readbuf[MAXLINE]; |
813 | int readsize = 0; | ||
814 | struct sendbuf write_std; | 751 | struct sendbuf write_std; |
815 | write_std.size = 0; | 752 | ssize_t ret; |
816 | write_std.pos = 0; | 753 | int maxfd; |
817 | |||
818 | struct sendbuf write_pout; | ||
819 | write_pout.size = 0; | ||
820 | write_pout.pos = 0; | ||
821 | |||
822 | dev.write_pout = &write_pout; | ||
823 | |||
824 | int ret = 0; | ||
825 | int maxfd = 0; | ||
826 | |||
827 | fd_set rfds; | 754 | fd_set rfds; |
828 | fd_set wfds; | 755 | fd_set wfds; |
829 | struct timeval tv; | ||
830 | int retval; | 756 | int retval; |
831 | 757 | int stdin_open; | |
832 | struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; | 758 | struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; |
833 | 759 | ||
834 | fdpin = dev.fd_in; | 760 | if (2 != argc) |
835 | fdpout = dev.fd_out; | ||
836 | |||
837 | stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev); | ||
838 | |||
839 | //send mac first | ||
840 | |||
841 | write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac); | ||
842 | |||
843 | //wait | ||
844 | tv.tv_sec = 2; | ||
845 | tv.tv_usec = 0; | ||
846 | retval = select(0, NULL, NULL, NULL, &tv); | ||
847 | |||
848 | while (0 == closeprog) | ||
849 | { | 761 | { |
762 | fprintf (stderr, | ||
763 | "This program must be started with the interface argument.\n"); | ||
764 | fprintf (stderr, | ||
765 | "Usage: interface-name\n"); | ||
766 | return 1; | ||
767 | } | ||
768 | if (0 != wlaninit(&dev, argv[1])) | ||
769 | return 1; | ||
770 | uid = getuid(); | ||
771 | if (0 != setresuid(uid, uid, uid)) | ||
772 | { | ||
773 | fprintf(stderr, | ||
774 | "Failed to setresuid: %s\n", | ||
775 | strerror(errno)); | ||
776 | /* not critical, continue anyway */ | ||
777 | } | ||
850 | 778 | ||
851 | //write_pout.size = maketest(write_pout.buf, &dev); | 779 | dev.write_pout.size = 0; |
852 | //tv.tv_sec = 2; | 780 | dev.write_pout.pos = 0; |
853 | //tv.tv_usec = 0; | 781 | stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev); |
854 | //select(0, NULL, NULL, NULL, &tv); | ||
855 | |||
856 | maxfd = 0; | ||
857 | |||
858 | //set timeout | ||
859 | tv.tv_sec = 5; | ||
860 | tv.tv_usec = 0; | ||
861 | 782 | ||
862 | FD_ZERO(&rfds); | 783 | /* send mac to STDOUT first */ |
863 | // if output queue is empty | 784 | write_std.pos = 0; |
864 | if (0 == write_pout.size) | 785 | write_std.size = send_mac_to_plugin((char *) &write_std.buf, dev.pl_mac); |
865 | { | 786 | stdin_open = 1; |
866 | FD_SET(STDIN_FILENO, &rfds); | ||
867 | 787 | ||
868 | } | 788 | while (1) |
789 | { | ||
790 | maxfd = -1; | ||
791 | FD_ZERO (&rfds); | ||
792 | if ( (0 == dev.write_pout.size) && | ||
793 | (1 == stdin_open) ) | ||
794 | { | ||
795 | FD_SET (STDIN_FILENO, &rfds); | ||
796 | maxfd = MAX (maxfd, STDIN_FILENO); | ||
797 | } | ||
869 | if (0 == write_std.size) | 798 | if (0 == write_std.size) |
870 | { | 799 | { |
871 | FD_SET(fdpin, &rfds); | 800 | FD_SET (dev.fd_raw, &rfds); |
872 | maxfd = fdpin; | 801 | maxfd = MAX(maxfd, dev.fd_raw); |
873 | } | 802 | } |
874 | FD_ZERO(&wfds); | 803 | FD_ZERO(&wfds); |
875 | // if there is something to write | ||
876 | if (0 < write_std.size) | 804 | if (0 < write_std.size) |
877 | { | 805 | { |
878 | FD_SET(STDOUT_FILENO, &wfds); | 806 | FD_SET (STDOUT_FILENO, &wfds); |
879 | maxfd = MAX(maxfd, STDOUT_FILENO); | 807 | maxfd = MAX(maxfd, STDOUT_FILENO); |
880 | } | 808 | } |
881 | 809 | if (0 < dev.write_pout.size) | |
882 | if (0 < write_pout.size) | ||
883 | { | ||
884 | FD_SET(fdpout, &wfds); | ||
885 | maxfd = MAX(maxfd, fdpout); | ||
886 | } | ||
887 | |||
888 | retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv); | ||
889 | |||
890 | if (-1 == retval && EINTR == errno) | ||
891 | { | 810 | { |
892 | continue; | 811 | FD_SET(dev.fd_raw, &wfds); |
812 | maxfd = MAX(maxfd, dev.fd_raw); | ||
893 | } | 813 | } |
814 | retval = select(maxfd + 1, &rfds, &wfds, NULL, NULL); | ||
815 | if ( (-1 == retval) && | ||
816 | (EINTR == errno) ) | ||
817 | continue; | ||
894 | if (0 > retval) | 818 | if (0 > retval) |
895 | { | 819 | { |
896 | fprintf(stderr, "select failed: %s\n", strerror(errno)); | 820 | fprintf(stderr, |
897 | exit(1); | 821 | "select failed: %s\n", |
822 | strerror(errno)); | ||
823 | break; | ||
898 | } | 824 | } |
899 | 825 | ||
900 | if (FD_ISSET(STDOUT_FILENO, &wfds)) | 826 | if (FD_ISSET(STDOUT_FILENO, &wfds)) |
901 | { | 827 | { |
902 | ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, | 828 | ret = write(STDOUT_FILENO, |
903 | write_std.size - write_std.pos); | 829 | write_std.buf + write_std.pos, |
904 | 830 | write_std.size - write_std.pos); | |
905 | if (0 > ret) | 831 | if (0 > ret) |
906 | { | 832 | { |
907 | closeprog = 1; | 833 | fprintf (stderr, |
908 | fprintf(stderr, "Write ERROR to STDOUT\n"); | 834 | "Failed to write to STDOUT: %s\n", |
909 | goto end; | 835 | strerror (errno)); |
910 | } | 836 | break; |
911 | else | ||
912 | { | ||
913 | write_std.pos += ret; | ||
914 | // check if finished | ||
915 | if (write_std.pos == write_std.size) | ||
916 | { | ||
917 | write_std.pos = 0; | ||
918 | write_std.size = 0; | ||
919 | } | ||
920 | } | 837 | } |
921 | } | 838 | write_std.pos += ret; |
922 | 839 | if (write_std.pos == write_std.size) | |
923 | if (FD_ISSET(fdpout, &wfds)) | 840 | { |
841 | write_std.pos = 0; | ||
842 | write_std.size = 0; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | if (FD_ISSET(dev.fd_raw, &wfds)) | ||
924 | { | 847 | { |
925 | 848 | ret = write (dev.fd_raw, | |
926 | ret = linux_write(&dev, write_pout.buf, write_pout.size); | 849 | dev.write_pout.buf, |
927 | 850 | dev.write_pout.size); | |
928 | if (0 > ret) | 851 | if (0 > ret) |
929 | { | 852 | { |
930 | closeprog = 1; | 853 | fprintf (stderr, |
931 | fprintf(stderr, "Write ERROR to fdpout\n"); | 854 | "Failed to write to WLAN device: %s\n", |
932 | } | 855 | strerror (errno)); |
933 | else | 856 | break; |
934 | { | 857 | } |
935 | write_pout.pos += ret; | 858 | dev.write_pout.pos += ret; |
936 | // check if finished | 859 | if ( (dev.write_pout.pos != dev.write_pout.size) && |
937 | if (write_pout.pos != write_pout.size && ret != 0) | 860 | (ret != 0) ) |
938 | { | 861 | { |
939 | closeprog = 1; | 862 | fprintf(stderr, |
940 | fprintf(stderr, | 863 | "Write error, partial send: %u/%u\n", |
941 | "Write ERROR packet not in one piece send: %u, %u\n", | 864 | dev.write_pout.pos, dev.write_pout.size); |
942 | write_pout.pos, write_pout.size); | 865 | break; |
943 | } | 866 | } |
944 | else if (write_pout.pos == write_pout.size) | 867 | if (dev.write_pout.pos == dev.write_pout.size) |
945 | { | 868 | { |
946 | write_pout.pos = 0; | 869 | dev.write_pout.pos = 0; |
947 | write_pout.size = 0; | 870 | dev.write_pout.size = 0; |
948 | } | 871 | } |
949 | |||
950 | } | ||
951 | } | 872 | } |
952 | 873 | ||
953 | if (FD_ISSET(STDIN_FILENO, &rfds)) | 874 | if (FD_ISSET(STDIN_FILENO, &rfds)) |
954 | { | 875 | { |
955 | readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf)); | 876 | ret = read(STDIN_FILENO, readbuf, sizeof(readbuf)); |
956 | 877 | if (0 > ret) | |
957 | if (0 > readsize) | ||
958 | { | ||
959 | closeprog = 1; | ||
960 | fprintf(stderr, "Read ERROR to STDIN_FILENO\n"); | ||
961 | } | ||
962 | else if (0 < readsize) | ||
963 | { | ||
964 | GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize, | ||
965 | GNUNET_NO, GNUNET_NO); | ||
966 | |||
967 | } | ||
968 | else | ||
969 | { | 878 | { |
970 | //eof | 879 | fprintf(stderr, |
971 | closeprog = 1; | 880 | "Read error from STDIN: %s\n", |
881 | strerror (errno)); | ||
882 | break; | ||
972 | } | 883 | } |
884 | if (0 == ret) | ||
885 | { | ||
886 | /* stop reading... */ | ||
887 | stdin_open = 0; | ||
888 | } | ||
889 | GNUNET_SERVER_mst_receive (stdin_mst, NULL, | ||
890 | readbuf, ret, | ||
891 | GNUNET_NO, GNUNET_NO); | ||
973 | } | 892 | } |
974 | 893 | ||
975 | if (FD_ISSET(fdpin, &rfds)) | 894 | if (FD_ISSET(dev.fd_raw, &rfds)) |
976 | { | 895 | { |
977 | rxinfo = (struct Radiotap_rx *) (write_std.buf | 896 | struct GNUNET_MessageHeader * header; |
978 | + sizeof(struct GNUNET_MessageHeader)); | 897 | struct Radiotap_rx * rxinfo; |
979 | datastart = (unsigned char *) write_std.buf | 898 | struct ieee80211_frame * datastart; |
980 | + sizeof(struct Radiotap_rx) | 899 | |
981 | + sizeof(struct GNUNET_MessageHeader); | 900 | header = (struct GNUNET_MessageHeader *) write_std.buf; |
982 | 901 | rxinfo = (struct Radiotap_rx *) &header[1]; | |
983 | readsize = linux_read(&dev, datastart, sizeof(write_std.buf) | 902 | datastart = (struct ieee80211_frame *) &rxinfo[1]; |
984 | - sizeof(struct Radiotap_rx) | 903 | ret = linux_read (&dev, |
985 | - sizeof(struct GNUNET_MessageHeader), rxinfo); | 904 | (unsigned char *) datastart, |
986 | 905 | sizeof(write_std.buf) - sizeof(struct Radiotap_rx) - sizeof(struct GNUNET_MessageHeader), | |
987 | if (0 > readsize) | 906 | rxinfo); |
907 | if (0 > ret) | ||
988 | { | 908 | { |
989 | closeprog = 1; | 909 | fprintf(stderr, |
990 | fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno)); | 910 | "Read error from raw socket: %s\n", |
991 | closeprog = 1; | 911 | strerror(errno)); |
912 | break; | ||
992 | } | 913 | } |
993 | else if (0 < readsize) | 914 | if ( (0 < ret) && |
994 | { | 915 | (0 == mac_test(datastart, &dev)) ) |
995 | if (1 == mac_test(datastart, &dev)) | 916 | { |
996 | { | 917 | write_std.size = ret + sizeof(struct GNUNET_MessageHeader) + sizeof(struct Radiotap_rx); |
997 | // mac wrong | 918 | header->size = htons(write_std.size); |
998 | write_std.pos = 0; | 919 | header->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); |
999 | write_std.size = 0; | ||
1000 | } | ||
1001 | else | ||
1002 | { | ||
1003 | header = (struct GNUNET_MessageHeader *) write_std.buf; | ||
1004 | write_std.size = readsize | ||
1005 | + sizeof(struct GNUNET_MessageHeader) | ||
1006 | + sizeof(struct Radiotap_rx); | ||
1007 | header->size = htons(write_std.size); | ||
1008 | header->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1009 | fprintf(stderr, "Got packet with size: %u, size std %u\n", | ||
1010 | readsize, write_std.size); | ||
1011 | |||
1012 | } | ||
1013 | } | 920 | } |
1014 | } | 921 | } |
1015 | 922 | ||
1016 | } | 923 | } |
1017 | 924 | /* Error handling, try to clean up a bit at least */ | |
1018 | GNUNET_SERVER_mst_destroy(stdin_mst); | 925 | GNUNET_SERVER_mst_destroy(stdin_mst); |
1019 | return 0; | 926 | close (dev.fd_raw); |
1020 | 927 | return 1; | |
1021 | end: GNUNET_SERVER_mst_destroy(stdin_mst); | ||
1022 | return 1; | ||
1023 | |||
1024 | } | 928 | } |
1025 | 929 | ||
1026 | int | 930 | int |
1027 | main(int argc, char *argv[]) | 931 | main(int argc, char *argv[]) |
1028 | { | 932 | { |
1029 | int ret = 0; | ||
1030 | if (3 != argc) | 933 | if (3 != argc) |
1031 | { | 934 | { |
1032 | fprintf( | 935 | fprintf (stderr, |
1033 | stderr, | 936 | "This program must be started with the interface and the operating mode as argument.\n"); |
1034 | "This program must be started with the interface and the operating mode as argument.\n"); | 937 | fprintf (stderr, |
1035 | usage(); | 938 | "Usage: interface-name options\n" |
939 | "options: 0 = with hardware\n" | ||
940 | "1 = first loopback file\n" | ||
941 | "2 = second loopback file\n" | ||
942 | "\n"); | ||
1036 | return 1; | 943 | return 1; |
1037 | } | 944 | } |
1038 | |||
1039 | if (strstr(argv[2], "1") || strstr(argv[2], "2")) | 945 | if (strstr(argv[2], "1") || strstr(argv[2], "2")) |
1040 | { | 946 | return testmode(argc, argv); |
1041 | 947 | return hardwaremode(argc - 1, argv); | |
1042 | ret = testmode(argc, argv); | ||
1043 | } | ||
1044 | else | ||
1045 | { | ||
1046 | |||
1047 | ret = hardwaremode(argc, argv); | ||
1048 | } | ||
1049 | |||
1050 | return ret; | ||
1051 | maketest(NULL, NULL); | ||
1052 | } | 948 | } |
1053 | |||
diff --git a/src/transport/wlan/loopback_helper.c b/src/transport/wlan/loopback_helper.c index aa3b6d8af..54bd9e955 100644 --- a/src/transport/wlan/loopback_helper.c +++ b/src/transport/wlan/loopback_helper.c | |||
@@ -108,6 +108,10 @@ file_in_send(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) | |||
108 | write_std->size += sendsize; | 108 | write_std->size += sendsize; |
109 | } | 109 | } |
110 | 110 | ||
111 | int closeprog; | ||
112 | |||
113 | |||
114 | |||
111 | int | 115 | int |
112 | testmode(int argc, char *argv[]) | 116 | testmode(int argc, char *argv[]) |
113 | { | 117 | { |