run indent twice, it alternates between two 'canonical' forms, also run whitespace...
[oweals/gnunet.git] / src / transport / gnunet-transport-wlan-helper.c
1 /*
2  This file is part of GNUnet.
3  (C) 2010, 2011 Christian Grothoff (and other contributing authors)
4
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
7  by the Free Software Foundation; either version 3, or (at your
8  option) any later version.
9
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  General Public License for more details.
14
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
17  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file src/transport/gnunet-transport-wlan-helper.c
23  * @brief wlan layer two server; must run as root (SUID will do)
24  *        This code will work under GNU/Linux only.
25  * @author David Brodski
26  *
27  * This program serves as the mediator between the wlan interface and
28  * gnunet
29  */
30
31 #define _GNU_SOURCE
32 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 #include <sys/wait.h>
37 #include <sys/time.h>
38 #include <sys/stat.h>
39 #include <netpacket/packet.h>
40 #include <linux/if_ether.h>
41 #include <linux/if.h>
42 #include <linux/wireless.h>
43 #include <netinet/in.h>
44 #include <linux/if_tun.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <stdarg.h>
49 #include <fcntl.h>
50 #include <errno.h>
51 #include <dirent.h>
52 //#include <sys/utsname.h>
53 #include <sys/param.h>
54
55 /*
56  //#include <resolv.h>
57  #include <string.h>
58  #include <utime.h>
59  #include <getopt.h>
60  */
61 //#include "platform.h"
62 #include "gnunet_constants.h"
63 #include "gnunet_os_lib.h"
64 #include "gnunet_transport_plugin.h"
65 #include "transport.h"
66 #include "gnunet_util_lib.h"
67 #include "plugin_transport_wlan.h"
68 #include "gnunet_common.h"
69 #include "gnunet-transport-wlan-helper.h"
70 #include "gnunet_crypto_lib.h"
71
72 #include "wlan/radiotap-parser.h"
73 /* radiotap-parser defines types like u8 that
74  * ieee80211_radiotap.h needs
75  *
76  * we use our local copy of ieee80211_radiotap.h
77  *
78  * - since we can't support extensions we don't understand
79  * - since linux does not include it in userspace headers
80  */
81 #include "wlan/ieee80211_radiotap.h"
82 #include "wlan/crctable_osdep.h"
83 #include "wlan/loopback_helper.h"
84 #include "wlan/ieee80211.h"
85
86 #define ARPHRD_IEEE80211        801
87 #define ARPHRD_IEEE80211_PRISM  802
88 #define ARPHRD_IEEE80211_FULL   803
89
90 #include "wlan/loopback_helper.h"
91
92 #define DEBUG 1
93
94 #define MAC_ADDR_SIZE 6
95
96 struct Hardware_Infos
97 {
98
99   struct sendbuf write_pout;
100   int fd_raw;
101   int arptype_in;
102
103   /**
104    * Name of the interface, not necessarily 0-terminated (!).
105    */
106   char iface[IFNAMSIZ];
107   unsigned char pl_mac[MAC_ADDR_SIZE];
108 };
109
110 // FIXME: inline?
111 int
112 getChannelFromFrequency (int frequency);
113
114 // FIXME: make nice...
115 static unsigned long
116 calc_crc_osdep (unsigned char *buf, int len)
117 {
118   unsigned long crc = 0xFFFFFFFF;
119
120   for (; len > 0; len--, buf++)
121     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
122
123   return (~crc);
124 }
125
126 /* CRC checksum verification routine */
127
128 // FIXME: make nice...
129 static int
130 check_crc_buf_osdep (unsigned char *buf, int len)
131 {
132   unsigned long crc;
133
134   if (0 > len)
135     return 0;
136
137   crc = calc_crc_osdep (buf, len);
138   buf += len;
139   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
140           ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
141 }
142
143
144 // FIXME: make nice...
145 static int
146 linux_get_channel (struct Hardware_Infos *dev)
147 {
148   struct iwreq wrq;
149   int fd, frequency;
150   int chan = 0;
151
152   memset (&wrq, 0, sizeof (struct iwreq));
153
154   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
155
156   fd = dev->fd_raw;
157   if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
158     return (-1);
159
160   frequency = wrq.u.freq.m;
161   if (100000000 < frequency)
162     frequency /= 100000;
163   else if (1000000 < frequency)
164     frequency /= 1000;
165
166   if (1000 < frequency)
167     chan = getChannelFromFrequency (frequency);
168   else
169     chan = frequency;
170
171   return chan;
172 }
173
174
175 // FIXME: make nice...
176 static ssize_t
177 linux_read (struct Hardware_Infos *dev, unsigned char *buf,     /* FIXME: void*? */
178             size_t buf_size, struct Radiotap_rx *ri)
179 {
180   unsigned char tmpbuf[buf_size];
181   ssize_t caplen;
182   int n, got_signal, got_noise, got_channel, fcs_removed;
183
184   n = got_signal = got_noise = got_channel = fcs_removed = 0;
185
186   caplen = read (dev->fd_raw, tmpbuf, buf_size);
187   if (0 > caplen)
188   {
189     if (EAGAIN == errno)
190       return 0;
191     fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
192     return -1;
193   }
194
195   memset (buf, 0, buf_size);
196   memset (ri, 0, sizeof (*ri));
197
198   switch (dev->arptype_in)
199   {
200   case ARPHRD_IEEE80211_PRISM:
201   {
202     /* skip the prism header */
203     if (tmpbuf[7] == 0x40)
204     {
205       /* prism54 uses a different format */
206       ri->ri_power = tmpbuf[0x33];
207       ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
208       ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
209       got_signal = 1;
210       got_noise = 1;
211       n = 0x40;
212     }
213     else
214     {
215       ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48);
216       ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
217       ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
218       ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
219       ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
220       got_channel = 1;
221       got_signal = 1;
222       got_noise = 1;
223       n = *(int *) (tmpbuf + 4);
224     }
225
226     if (n < 8 || n >= caplen)
227       return (0);
228   }
229     break;
230
231   case ARPHRD_IEEE80211_FULL:
232   {
233     struct ieee80211_radiotap_iterator iterator;
234     struct ieee80211_radiotap_header *rthdr;
235
236     rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
237
238     if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
239       return (0);
240
241     /* go through the radiotap arguments we have been given
242      * by the driver
243      */
244
245     while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
246     {
247
248       switch (iterator.this_arg_index)
249       {
250
251       case IEEE80211_RADIOTAP_TSFT:
252         ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg));
253         break;
254
255       case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
256         if (!got_signal)
257         {
258           if (*iterator.this_arg < 127)
259             ri->ri_power = *iterator.this_arg;
260           else
261             ri->ri_power = *iterator.this_arg - 255;
262
263           got_signal = 1;
264         }
265         break;
266
267       case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
268         if (!got_signal)
269         {
270           if (*iterator.this_arg < 127)
271             ri->ri_power = *iterator.this_arg;
272           else
273             ri->ri_power = *iterator.this_arg - 255;
274
275           got_signal = 1;
276         }
277         break;
278
279       case IEEE80211_RADIOTAP_DBM_ANTNOISE:
280         if (!got_noise)
281         {
282           if (*iterator.this_arg < 127)
283             ri->ri_noise = *iterator.this_arg;
284           else
285             ri->ri_noise = *iterator.this_arg - 255;
286
287           got_noise = 1;
288         }
289         break;
290
291       case IEEE80211_RADIOTAP_DB_ANTNOISE:
292         if (!got_noise)
293         {
294           if (*iterator.this_arg < 127)
295             ri->ri_noise = *iterator.this_arg;
296           else
297             ri->ri_noise = *iterator.this_arg - 255;
298
299           got_noise = 1;
300         }
301         break;
302
303       case IEEE80211_RADIOTAP_ANTENNA:
304         ri->ri_antenna = *iterator.this_arg;
305         break;
306
307       case IEEE80211_RADIOTAP_CHANNEL:
308         ri->ri_channel = *iterator.this_arg;
309         got_channel = 1;
310         break;
311
312       case IEEE80211_RADIOTAP_RATE:
313         ri->ri_rate = (*iterator.this_arg) * 500000;
314         break;
315
316       case IEEE80211_RADIOTAP_FLAGS:
317         /* is the CRC visible at the end?
318          * remove
319          */
320         if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
321         {
322           fcs_removed = 1;
323           caplen -= 4;
324         }
325
326         if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
327           return (0);
328
329         break;
330       }
331     }
332     n = le16_to_cpu (rthdr->it_len);
333     if (n <= 0 || n >= caplen)
334       return 0;
335   }
336     break;
337   case ARPHRD_IEEE80211:
338     /* do nothing? */
339     break;
340   default:
341     errno = ENOTSUP;
342     return -1;
343   }
344
345   caplen -= n;
346
347   //detect fcs at the end, even if the flag wasn't set and remove it
348   if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
349   {
350     caplen -= 4;
351   }
352   memcpy (buf, tmpbuf + n, caplen);
353   if (!got_channel)
354     ri->ri_channel = linux_get_channel (dev);
355
356   return caplen;
357 }
358
359
360 /**
361  * @return 0 on success
362  */
363 static int
364 openraw (struct Hardware_Infos *dev)
365 {
366   struct ifreq ifr;
367   struct iwreq wrq;
368   struct packet_mreq mr;
369   struct sockaddr_ll sll;
370
371   /* find the interface index */
372   memset (&ifr, 0, sizeof (ifr));
373   strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
374   if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
375   {
376     fprintf (stderr,
377              "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
378              IFNAMSIZ, dev->iface, strerror (errno));
379     return 1;
380   }
381
382   /* lookup the hardware type */
383   memset (&sll, 0, sizeof (sll));
384   sll.sll_family = AF_PACKET;
385   sll.sll_ifindex = ifr.ifr_ifindex;
386   sll.sll_protocol = htons (ETH_P_ALL);
387   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
388   {
389     fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
390              IFNAMSIZ, dev->iface, strerror (errno));
391     return 1;
392   }
393
394   /* lookup iw mode */
395   memset (&wrq, 0, sizeof (struct iwreq));
396   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
397   if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
398   {
399     /* most probably not supported (ie for rtap ipw interface) *
400      * so just assume its correctly set...                     */
401     wrq.u.mode = IW_MODE_MONITOR;
402   }
403
404   if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
405        (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
406        (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
407       (wrq.u.mode != IW_MODE_MONITOR))
408   {
409     fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
410              IFNAMSIZ, dev->iface);
411     return 1;
412   }
413
414   /* Is interface st to up, broadcast & running ? */
415   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
416   {
417     /* Bring interface up */
418     ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
419
420     if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
421     {
422       fprintf (stderr,
423                "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
424                IFNAMSIZ, dev->iface, strerror (errno));
425       return 1;
426     }
427   }
428
429   /* bind the raw socket to the interface */
430   if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
431   {
432     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
433              dev->iface, strerror (errno));
434     return 1;
435   }
436
437   /* lookup the hardware type */
438   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
439   {
440     fprintf (stderr,
441              "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
442              IFNAMSIZ, dev->iface, strerror (errno));
443     return 1;
444   }
445
446   memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
447   dev->arptype_in = ifr.ifr_hwaddr.sa_family;
448   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
449       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
450       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
451   {
452     fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
453              ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
454     return 1;
455   }
456
457   /* enable promiscuous mode */
458   memset (&mr, 0, sizeof (mr));
459   mr.mr_ifindex = sll.sll_ifindex;
460   mr.mr_type = PACKET_MR_PROMISC;
461   if (0 !=
462       setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
463                   sizeof (mr)))
464   {
465     fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
466              IFNAMSIZ, dev->iface);
467     return 1;
468   }
469
470   return 0;
471 }
472
473 /**
474  * @return 0 on success
475  */
476 static int
477 wlaninit (struct Hardware_Infos *dev, const char *iface)
478 {
479   char strbuf[512];
480   struct stat sbuf;
481   int ret;
482
483   dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
484   if (0 > dev->fd_raw)
485   {
486     fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
487     return 1;
488   }
489   if (dev->fd_raw >= FD_SETSIZE)
490   {
491     fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
492              dev->fd_raw, FD_SETSIZE);
493     close (dev->fd_raw);
494     return 1;
495   }
496
497   /* mac80211 stack detection */
498   ret =
499       snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
500                 iface);
501   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
502   {
503     fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
504     close (dev->fd_raw);
505     return 1;
506   }
507   strncpy (dev->iface, iface, IFNAMSIZ);
508   if (0 != openraw (dev))
509   {
510     close (dev->fd_raw);
511     return 1;
512   }
513   return 0;
514 }
515
516
517 /**
518  * Function to test incoming packets mac for being our own.
519  *
520  * @param u8aIeeeHeader buffer of the packet
521  * @param dev the Hardware_Infos struct
522  * @return 0 if mac belongs to us, 1 if mac is for another target
523  */
524 static int
525 mac_test (const struct ieee80211_frame *u8aIeeeHeader,
526           const struct Hardware_Infos *dev)
527 {
528   if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
529     return 1;
530   if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE))
531     return 0;
532   if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
533     return 0;
534   return 1;
535 }
536
537
538 /**
539  * function to set the wlan header to make attacks more difficult
540  * @param buf buffer of the packet
541  * @param dev pointer to the Hardware_Infos struct
542  */
543 static void
544 mac_set (struct ieee80211_frame *u8aIeeeHeader,
545          const struct Hardware_Infos *dev)
546 {
547   u8aIeeeHeader->i_fc[0] = 0x08;
548   u8aIeeeHeader->i_fc[1] = 0x00;
549   memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
550   memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
551
552 }
553
554 struct RadioTapheader
555 {
556   struct ieee80211_radiotap_header header;
557   u8 rate;
558   u8 pad1;
559   u16 txflags;
560 };
561
562 static void
563 stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
564 {
565   struct Hardware_Infos *dev = cls;
566   struct sendbuf *write_pout = &dev->write_pout;
567   struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
568   struct ieee80211_frame *wlanheader;
569   size_t sendsize;
570
571   // struct? // FIXME: make nice...
572   struct RadioTapheader rtheader;
573
574   rtheader.header.it_version = 0;
575   rtheader.header.it_len = htole16 (0x0c);
576   rtheader.header.it_present = htole32 (0x00008004);
577   rtheader.rate = 0x00;
578   rtheader.txflags =
579       htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
580
581   /*  { 0x00, 0x00, <-- radiotap version
582    * 0x0c, 0x00, <- radiotap header length
583    * 0x04, 0x80, 0x00, 0x00,  <-- bitmap
584    * 0x00,  <-- rate
585    * 0x00,  <-- padding for natural alignment
586    * 0x18, 0x00,  <-- TX flags
587    * }; */
588
589   sendsize = ntohs (hdr->size);
590   if (sendsize <
591       sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
592   {
593     fprintf (stderr, "Function stdin_send_hw: mailformed packet (too small)\n");
594     exit (1);
595   }
596   sendsize -=
597       sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
598
599   if (MAXLINE < sendsize)
600   {
601     fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
602     exit (1);
603   }
604   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
605   {
606     fprintf (stderr, "Function stdin_send: wrong packet type\n");
607     exit (1);
608   }
609
610   rtheader.header.it_len = htole16 (sizeof (rtheader));
611   rtheader.rate = header->rate;
612   memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
613   memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
614   /* payload contains MAC address, but we don't trust it, so we'll
615    * overwrite it with OUR MAC address again to prevent mischief */
616   wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
617   mac_set (wlanheader, dev);
618   write_pout->size = sendsize + sizeof (rtheader);
619 }
620
621 #if 0
622 static int
623 maketest (unsigned char *buf, struct Hardware_Infos *dev)
624 {
625   uint16_t *tmp16;
626   static uint16_t seqenz = 0;
627   static int first = 0;
628
629   const int rate = 11000000;
630   static const char txt[] =
631       "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
632
633   unsigned char u8aRadiotap[] = { 0x00, 0x00,   // <-- radiotap version
634     0x00, 0x00,                 // <- radiotap header length
635     0x04, 0x80, 0x02, 0x00,     // <-- bitmap
636     0x00,                       // <-- rate
637     0x00,                       // <-- padding for natural alignment
638     0x10, 0x00,                 // <-- TX flags
639     0x04                        //retries
640   };
641
642   /*uint8_t u8aRadiotap[] =
643    * {
644    * 0x00, 0x00, // <-- radiotap version
645    * 0x19, 0x00, // <- radiotap header length
646    * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
647    * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
648    * 0x00, // <-- flags (Offset +0x10)
649    * 0x6c, // <-- rate (0ffset +0x11)
650    * 0x71, 0x09, 0xc0, 0x00, // <-- channel
651    * 0xde, // <-- antsignal
652    * 0x00, // <-- antnoise
653    * 0x01, // <-- antenna
654    * }; */
655
656   u8aRadiotap[8] = (rate / 500000);
657   u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
658
659   static struct ieee80211_frame u8aIeeeHeader;
660
661   uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00,   // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
662     //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
663     //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
664     0x00, 0x00,                 // Duration/ID
665
666     //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
667     0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
668     0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
669     //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
670     0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
671     0x10, 0x86,                 //Sequence Control
672   };
673   if (0 == first)
674   {
675     memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
676     memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
677     first = 1;
678   }
679
680   tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
681   *tmp16 =
682       (uint16_t)
683       htole16 ((sizeof (txt) +
684                 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
685   tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
686   *tmp16 =
687       (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
688                                             IEEE80211_SEQ_SEQ_SHIFT);
689   seqenz++;
690
691   memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
692   memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
693   memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
694           sizeof (txt));
695   return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
696
697 }
698 #endif
699
700
701 /**
702  * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
703  * @param buffer pointer to buffer for the message
704  * @param mac pointer to the mac address
705  * @return number of bytes written
706  */
707 // FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file)
708 static int
709 send_mac_to_plugin (char *buffer, uint8_t * mac)
710 {
711   struct Wlan_Helper_Control_Message macmsg;
712
713   macmsg.hdr.size = htons (sizeof (struct Wlan_Helper_Control_Message));
714   macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
715   memcpy (macmsg.mac.mac, mac, sizeof (struct MacAddress));
716   memcpy (buffer, &macmsg, sizeof (struct Wlan_Helper_Control_Message));
717   return sizeof (struct Wlan_Helper_Control_Message);
718 }
719
720
721 static int
722 hardwaremode (int argc, char *argv[])
723 {
724   uid_t uid;
725   struct Hardware_Infos dev;
726   char readbuf[MAXLINE];
727   struct sendbuf write_std;
728   ssize_t ret;
729   int maxfd;
730   fd_set rfds;
731   fd_set wfds;
732   int retval;
733   int stdin_open;
734   struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
735
736   if (0 != wlaninit (&dev, argv[1]))
737     return 1;
738   uid = getuid ();
739   if (0 != setresuid (uid, uid, uid))
740   {
741     fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
742     /* not critical, continue anyway */
743   }
744
745   dev.write_pout.size = 0;
746   dev.write_pout.pos = 0;
747   stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
748
749   /* send mac to STDOUT first */
750   write_std.pos = 0;
751   write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac);
752   stdin_open = 1;
753
754   while (1)
755   {
756     maxfd = -1;
757     FD_ZERO (&rfds);
758     if ((0 == dev.write_pout.size) && (1 == stdin_open))
759     {
760       FD_SET (STDIN_FILENO, &rfds);
761       maxfd = MAX (maxfd, STDIN_FILENO);
762     }
763     if (0 == write_std.size)
764     {
765       FD_SET (dev.fd_raw, &rfds);
766       maxfd = MAX (maxfd, dev.fd_raw);
767     }
768     FD_ZERO (&wfds);
769     if (0 < write_std.size)
770     {
771       FD_SET (STDOUT_FILENO, &wfds);
772       maxfd = MAX (maxfd, STDOUT_FILENO);
773     }
774     if (0 < dev.write_pout.size)
775     {
776       FD_SET (dev.fd_raw, &wfds);
777       maxfd = MAX (maxfd, dev.fd_raw);
778     }
779     retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
780     if ((-1 == retval) && (EINTR == errno))
781       continue;
782     if (0 > retval)
783     {
784       fprintf (stderr, "select failed: %s\n", strerror (errno));
785       break;
786     }
787
788     if (FD_ISSET (STDOUT_FILENO, &wfds))
789     {
790       ret =
791           write (STDOUT_FILENO, write_std.buf + write_std.pos,
792                  write_std.size - write_std.pos);
793       if (0 > ret)
794       {
795         fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
796         break;
797       }
798       write_std.pos += ret;
799       if (write_std.pos == write_std.size)
800       {
801         write_std.pos = 0;
802         write_std.size = 0;
803       }
804     }
805
806     if (FD_ISSET (dev.fd_raw, &wfds))
807     {
808       ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
809       if (0 > ret)
810       {
811         fprintf (stderr,
812                  "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n",
813                  __LINE__, strerror (errno), dev.write_pout.size);
814         break;
815       }
816       dev.write_pout.pos += ret;
817       if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
818       {
819         fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n",
820                  __LINE__, dev.write_pout.pos, dev.write_pout.size);
821         break;
822       }
823       if (dev.write_pout.pos == dev.write_pout.size)
824       {
825         dev.write_pout.pos = 0;
826         dev.write_pout.size = 0;
827       }
828     }
829
830     if (FD_ISSET (STDIN_FILENO, &rfds))
831     {
832       ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
833       if (0 > ret)
834       {
835         fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
836         break;
837       }
838       if (0 == ret)
839       {
840         /* stop reading... */
841         stdin_open = 0;
842       }
843       GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
844                                  GNUNET_NO);
845     }
846
847     if (FD_ISSET (dev.fd_raw, &rfds))
848     {
849       struct GNUNET_MessageHeader *header;
850       struct Radiotap_rx *rxinfo;
851       struct ieee80211_frame *datastart;
852
853       header = (struct GNUNET_MessageHeader *) write_std.buf;
854       rxinfo = (struct Radiotap_rx *) &header[1];
855       datastart = (struct ieee80211_frame *) &rxinfo[1];
856       ret =
857           linux_read (&dev, (unsigned char *) datastart,
858                       sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
859                       sizeof (struct GNUNET_MessageHeader), rxinfo);
860       if (0 > ret)
861       {
862         fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
863         break;
864       }
865       if ((0 < ret) && (0 == mac_test (datastart, &dev)))
866       {
867         write_std.size =
868             ret + sizeof (struct GNUNET_MessageHeader) +
869             sizeof (struct Radiotap_rx);
870         header->size = htons (write_std.size);
871         header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
872       }
873     }
874
875   }
876   /* Error handling, try to clean up a bit at least */
877   GNUNET_SERVER_mst_destroy (stdin_mst);
878   close (dev.fd_raw);
879   return 1;
880 }
881
882 int
883 main (int argc, char *argv[])
884 {
885   if (2 != argc)
886   {
887     fprintf (stderr,
888              "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
889              __TIMESTAMP__);
890     fprintf (stderr, "Usage: interface-name\n" "\n");
891     return 1;
892   }
893   return hardwaremode (argc, argv);
894 }