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