633b2776c9ed3e083683bd3235207f26960ad0c4
[oweals/gnunet.git] / src / transport / gnunet-transport-wlan-helper.c
1 /*
2  This file is part of GNUnet.
3  (C) 2010 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 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <netpacket/packet.h>
39 #include <linux/if_ether.h>
40 #include <linux/if.h>
41 #include <linux/wireless.h>
42 #include <netinet/in.h>
43 #include <linux/if_tun.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <stdarg.h>
48 #include <unistd.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 <unistd.h>
60  #include <getopt.h>
61  */
62 //#include "platform.h"
63 #include "gnunet_constants.h"
64 #include "gnunet_os_lib.h"
65 #include "gnunet_transport_plugin.h"
66 #include "transport.h"
67 #include "gnunet_util_lib.h"
68 #include "plugin_transport_wlan.h"
69 #include "gnunet_common.h"
70 #include "gnunet-transport-wlan-helper.h"
71 #include "gnunet_crypto_lib.h"
72
73 #include <pcap.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <sys/stat.h>
77
78 #include "wlan/radiotap-parser.h"
79 /* radiotap-parser defines types like u8 that
80  * ieee80211_radiotap.h needs
81  *
82  * we use our local copy of ieee80211_radiotap.h
83  *
84  * - since we can't support extensions we don't understand
85  * - since linux does not include it in userspace headers
86  */
87 #include "wlan/ieee80211_radiotap.h"
88 #include "wlan/crctable_osdep.h"
89 #include "wlan/loopback_helper.h"
90 #include "wlan/ieee80211.h"
91
92 #define ARPHRD_IEEE80211        801
93 #define ARPHRD_IEEE80211_PRISM  802
94 #define ARPHRD_IEEE80211_FULL   803
95
96 int closeprog;
97
98 #include "wlan/helper_common.h"
99 #include "wlan/loopback_helper.h"
100
101 #define DEBUG 1
102
103 typedef enum
104 {
105   DT_NULL = 0,
106   DT_WLANNG,
107   DT_HOSTAP,
108   DT_MADWIFI,
109   DT_MADWIFING,
110   DT_BCM43XX,
111   DT_ORINOCO,
112   DT_ZD1211RW,
113   DT_ACX,
114   DT_MAC80211_RT,
115   DT_AT76USB,
116   DT_IPW2200
117
118 } DRIVER_TYPE;
119
120 static const char * szaDriverTypes[] =
121   { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP",
122       [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG",
123       [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco",
124       [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX",
125       [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb",
126       [DT_IPW2200] = "ipw2200" };
127
128 struct Hardware_Infos
129 {
130
131   struct sendbuf *write_pout;
132   int fd_in, arptype_in;
133   int fd_out;
134
135   DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */
136
137   char *iface;
138   unsigned char pl_mac[6];
139 };
140
141
142 /* wifi bitrate to use in 500kHz units */
143
144 /*
145  static const u8 u8aRatesToUse[] =
146  {
147
148  54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5
149  2 * 2, 1 * 2 };
150
151 */
152 static void
153 sigfunc_hw(int sig)
154 {
155   closeprog = 1;
156 }
157
158 static void
159 usage()
160 {
161   printf("Usage: interface-name options\n"
162     "options: 0 = with hardware\n"
163     "1 = first loopback file\n"
164     "2 = second loopback file\n"
165     "\n");
166 }
167
168 static unsigned long
169 calc_crc_osdep(unsigned char * buf, int len)
170 {
171   unsigned long crc = 0xFFFFFFFF;
172
173   for (; len > 0; len--, buf++)
174     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
175
176   return (~crc);
177 }
178
179 /* CRC checksum verification routine */
180
181 static int
182 check_crc_buf_osdep(unsigned char *buf, int len)
183 {
184   unsigned long crc;
185
186   if (0 > len)
187     return 0;
188
189   crc = calc_crc_osdep(buf, len);
190   buf += len;
191   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc
192       >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
193 }
194
195 static int
196 linux_get_channel(struct Hardware_Infos *dev)
197 {
198   struct iwreq wrq;
199   int fd, frequency;
200   int chan = 0;
201
202   memset(&wrq, 0, sizeof(struct iwreq));
203
204   strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
205
206   fd = dev->fd_in;
207   if (0 > ioctl(fd, SIOCGIWFREQ, &wrq))
208     return (-1);
209
210   frequency = wrq.u.freq.m;
211   if (100000000 < frequency  )
212     frequency /= 100000;
213   else if (1000000 < frequency )
214     frequency /= 1000;
215
216   if (1000 < frequency)
217     chan = getChannelFromFrequency(frequency);
218   else
219     chan = frequency;
220
221   return chan;
222 }
223
224 static int
225 linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count,
226     struct Radiotap_rx * ri)
227 {
228   unsigned char tmpbuf[4096 * 4];
229
230   int caplen, n, got_signal, got_noise, got_channel, fcs_removed;
231
232   caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0;
233
234   if ((unsigned) count > sizeof(tmpbuf))
235     return (-1);
236   caplen = read(dev->fd_in, tmpbuf, count);
237   if (0 > caplen)
238     {
239       if (EAGAIN == errno)
240         return (0);
241
242       perror("read failed");
243       return (-1);
244     }
245
246   memset(buf, 0, sizeof(buf));
247
248   if (ri)
249     memset(ri, 0, sizeof(*ri));
250
251   if (ARPHRD_IEEE80211_PRISM == dev->arptype_in )
252     {
253       /* skip the prism header */
254       if (tmpbuf[7] == 0x40)
255         {
256           /* prism54 uses a different format */
257           if (ri)
258             {
259               ri->ri_power = tmpbuf[0x33];
260               ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
261               ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
262
263               got_signal = 1;
264               got_noise = 1;
265             }
266
267           n = 0x40;
268         }
269       else
270         {
271           if (ri)
272             {
273               ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48);
274               ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
275               ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
276               ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
277               ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
278
279               got_channel = 1;
280               got_signal = 1;
281               got_noise = 1;
282             }
283
284           n = *(int *) (tmpbuf + 4);
285         }
286
287       if (n < 8 || n >= caplen)
288         return (0);
289     }
290
291   if (ARPHRD_IEEE80211_FULL == dev->arptype_in)
292     {
293       struct ieee80211_radiotap_iterator iterator;
294       struct ieee80211_radiotap_header *rthdr;
295
296       rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
297
298       if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0)
299         return (0);
300
301       /* go through the radiotap arguments we have been given
302        * by the driver
303        */
304
305       while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0))
306         {
307
308           switch (iterator.this_arg_index)
309             {
310
311           case IEEE80211_RADIOTAP_TSFT:
312             ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg));
313             break;
314
315           case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
316             if (!got_signal)
317               {
318                 if (*iterator.this_arg < 127)
319                   ri->ri_power = *iterator.this_arg;
320                 else
321                   ri->ri_power = *iterator.this_arg - 255;
322
323                 got_signal = 1;
324               }
325             break;
326
327           case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
328             if (!got_signal)
329               {
330                 if (*iterator.this_arg < 127)
331                   ri->ri_power = *iterator.this_arg;
332                 else
333                   ri->ri_power = *iterator.this_arg - 255;
334
335                 got_signal = 1;
336               }
337             break;
338
339           case IEEE80211_RADIOTAP_DBM_ANTNOISE:
340             if (!got_noise)
341               {
342                 if (*iterator.this_arg < 127)
343                   ri->ri_noise = *iterator.this_arg;
344                 else
345                   ri->ri_noise = *iterator.this_arg - 255;
346
347                 got_noise = 1;
348               }
349             break;
350
351           case IEEE80211_RADIOTAP_DB_ANTNOISE:
352             if (!got_noise)
353               {
354                 if (*iterator.this_arg < 127)
355                   ri->ri_noise = *iterator.this_arg;
356                 else
357                   ri->ri_noise = *iterator.this_arg - 255;
358
359                 got_noise = 1;
360               }
361             break;
362
363           case IEEE80211_RADIOTAP_ANTENNA:
364             ri->ri_antenna = *iterator.this_arg;
365             break;
366
367           case IEEE80211_RADIOTAP_CHANNEL:
368             ri->ri_channel = *iterator.this_arg;
369             got_channel = 1;
370             break;
371
372           case IEEE80211_RADIOTAP_RATE:
373             ri->ri_rate = (*iterator.this_arg) * 500000;
374             break;
375
376           case IEEE80211_RADIOTAP_FLAGS:
377             /* is the CRC visible at the end?
378              * remove
379              */
380             if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
381               {
382                 fcs_removed = 1;
383                 caplen -= 4;
384               }
385
386             if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
387               return (0);
388
389             break;
390
391             }
392         }
393
394       n = le16_to_cpu(rthdr->it_len);
395
396       if (n <= 0 || n >= caplen)
397         return (0);
398     }
399
400   caplen -= n;
401
402   //detect fcs at the end, even if the flag wasn't set and remove it
403   if (0 == fcs_removed && 1== check_crc_buf_osdep(tmpbuf + n, caplen - 4))
404     {
405       caplen -= 4;
406     }
407
408   memcpy(buf, tmpbuf + n, caplen);
409
410   if (ri && !got_channel)
411     ri->ri_channel = linux_get_channel(dev);
412
413   return (caplen);
414 }
415
416 static int
417 linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count)
418 {
419   int ret;
420   //int usedrtap;
421   //unsigned short int *p_rtlen;
422
423   //unsigned char * u8aRadiotap = buf;
424
425   /* Pointer to the radiotap header length field for later use. */
426   //p_rtlen = (unsigned short int*) (u8aRadiotap + 2);
427   //usedrtap = 0;
428   ret = write(dev->fd_out, buf, count);
429
430   if (0 > ret)
431     {
432       if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
433           == ENOMEM)
434         {
435           usleep(10000);
436           return (0);
437         }
438
439       perror("write failed");
440       return (-1);
441     }
442
443   /* radiotap header length is stored little endian on all systems */
444   /*if (usedrtap)
445    ret -= letoh16(*p_rtlen);
446
447    if (0 > ret)
448    {
449    if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
450    == ENOMEM)
451    {
452    usleep(10000);
453    return (0);
454    }
455
456    perror("write failed");
457    return (-1);
458    }*/
459
460   return (ret);
461 }
462
463 static int
464 openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype,
465     uint8_t *mac)
466 {
467   struct ifreq ifr;
468   struct iwreq wrq;
469   struct packet_mreq mr;
470   struct sockaddr_ll sll;
471
472   /* find the interface index */
473
474   memset(&ifr, 0, sizeof(ifr));
475   strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
476
477   if (0 > ioctl(fd, SIOCGIFINDEX, &ifr))
478     {
479       printf("Interface %s: \n", iface);
480       perror("ioctl(SIOCGIFINDEX) failed");
481       return (1);
482     }
483
484   memset(&sll, 0, sizeof(sll));
485   sll.sll_family = AF_PACKET;
486   sll.sll_ifindex = ifr.ifr_ifindex;
487
488   sll.sll_protocol = htons(ETH_P_ALL);
489
490   /* lookup the hardware type */
491
492   if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr))
493     {
494       printf("Interface %s: \n", iface);
495       perror("ioctl(SIOCGIFHWADDR) failed");
496       return (1);
497     }
498
499   /* lookup iw mode */
500   memset(&wrq, 0, sizeof(struct iwreq));
501   strncpy(wrq.ifr_name, iface, IFNAMSIZ);
502
503   if (0 > ioctl(fd, SIOCGIWMODE, &wrq))
504     {
505       /* most probably not supported (ie for rtap ipw interface) *
506        * so just assume its correctly set...                     */
507       wrq.u.mode = IW_MODE_MONITOR;
508     }
509
510   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
511       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
512       != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR))
513     {
514       printf("Error: %s not in monitor mode\n", iface);
515       return (1);
516     }
517
518   /* Is interface st to up, broadcast & running ? */
519   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
520     {
521       /* Bring interface up*/
522       ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
523
524       if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
525         {
526           perror("ioctl(SIOCSIFFLAGS) failed");
527           return (1);
528         }
529     }
530   /* bind the raw socket to the interface */
531
532   if (0 > bind(fd, (struct sockaddr *) &sll, sizeof(sll)))
533     {
534       printf("Interface %s: \n", iface);
535       perror("bind(ETH_P_ALL) failed");
536       return (1);
537     }
538
539   /* lookup the hardware type */
540
541   if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr))
542     {
543       printf("Interface %s: \n", iface);
544       perror("ioctl(SIOCGIFHWADDR) failed");
545       return (1);
546     }
547
548   memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6);
549
550   *arptype = ifr.ifr_hwaddr.sa_family;
551
552   if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
553       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
554       != ARPHRD_IEEE80211_FULL)
555     {
556       if (1 == ifr.ifr_hwaddr.sa_family)
557         fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) ");
558       else
559         fprintf(stderr, "\nUnsupported hardware link type %4d ",
560             ifr.ifr_hwaddr.sa_family);
561
562       fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_"
563         "FULL or ARPHRD_IEEE80211_PRISM instead.  Make\n"
564         "sure RFMON is enabled: run 'airmon-ng start %s"
565         " <#>'\nSysfs injection support was not found "
566         "either.\n\n", iface);
567       return (1);
568     }
569
570   /* enable promiscuous mode */
571
572   memset(&mr, 0, sizeof(mr));
573   mr.mr_ifindex = sll.sll_ifindex;
574   mr.mr_type = PACKET_MR_PROMISC;
575
576   if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
577     {
578       perror("setsockopt(PACKET_MR_PROMISC) failed");
579       return (1);
580     }
581
582   return (0);
583 }
584
585 int
586 wlaninit(struct Hardware_Infos * dev, char *iface)
587 {
588   char strbuf[512];
589
590   dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
591   if (0 > dev->fd_out)
592     {
593       perror("socket(PF_PACKET) failed at fd_out");
594       goto close_in;
595     }
596
597   /* figure out device type */
598
599   /* mac80211 radiotap injection
600    * detected based on interface called mon...
601    * since mac80211 allows multiple virtual interfaces
602    *
603    * note though that the virtual interfaces are ultimately using a
604    * single physical radio: that means for example they must all
605    * operate on the same channel
606    */
607
608   /* mac80211 stack detection */
609   memset(strbuf, 0, sizeof(strbuf));
610   snprintf(strbuf, sizeof(strbuf) - 1,
611       "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface);
612
613   if (0 == system(strbuf))
614     dev->drivertype = DT_MAC80211_RT;
615
616   else
617     {
618       // At the moment only mac80211 tested
619       fprintf(stderr, "only mac80211 stack supported, exiting.\n");
620       return 1;
621     }
622
623 #ifdef DEBUG
624   fprintf(stderr, "Interface %s -> driver: %s\n", iface,
625       szaDriverTypes[dev->drivertype]);
626 #endif
627
628   if (openraw(dev, iface, dev->fd_out, &dev->arptype_in, dev->pl_mac) != 0)
629     {
630       goto close_out;
631     }
632
633   dev->fd_in = dev->fd_out;
634   dev->iface = GNUNET_malloc(sizeof(char) *6);
635   strncpy(dev->iface, iface, sizeof(char) * 6);
636
637
638   return 0;
639   close_out: close(dev->fd_out);
640   close_in: close(dev->fd_in);
641   return 1;
642 }
643
644 /**
645  * function to test incoming packets mac
646  * @param buf buffer of the packet
647  * @param dev pointer to the Hardware_Infos struct
648  * @return 0 if macs are okay, 1 if macs are wrong
649  */
650
651 static int
652 mac_test(unsigned char * buf, struct Hardware_Infos * dev)
653 {
654   struct ieee80211_frame * u8aIeeeHeader;
655   u8aIeeeHeader = (struct ieee80211_frame *) buf;
656   if (0 == memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, 6))
657     {
658       if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, 6))
659         {
660           return 0;
661         }
662
663       if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, 6))
664         {
665           return 0;
666         }
667     }
668
669   return 1;
670 }
671
672 /**
673  * function to set the wlan header to make attacks more difficult
674  * @param buf buffer of the packet
675  * @param dev pointer to the Hardware_Infos struct
676  */
677
678 static void
679 mac_set(unsigned char * buf, struct Hardware_Infos * dev)
680 {
681   struct ieee80211_frame * u8aIeeeHeader;
682   u8aIeeeHeader = (struct ieee80211_frame *) buf;
683
684   u8aIeeeHeader->i_fc[0] = 0x08;
685   u8aIeeeHeader->i_fc[1] = 0x00;
686
687   memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6);
688   memcpy(u8aIeeeHeader->i_addr3, &mac_bssid, 6);
689
690 }
691
692 static void
693 stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
694 {
695   struct Hardware_Infos * dev = cls;
696   struct sendbuf *write_pout = dev->write_pout;
697   struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1];
698   unsigned char * wlanheader;
699
700   int sendsize;
701
702   unsigned char u8aRadiotap[] =
703     { 0x00, 0x00, // <-- radiotap version
704         0x0c, 0x00, // <- radiotap header length
705         0x04, 0x80, 0x00, 0x00, // <-- bitmap
706         0x00, // <-- rate
707         0x00, // <-- padding for natural alignment
708         0x18, 0x00, // <-- TX flags
709       };
710
711   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
712       - sizeof(struct GNUNET_MessageHeader);
713
714   if (MAXLINE * 2 < sendsize)
715     {
716       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
717       exit(1);
718     }
719
720   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
721     {
722       fprintf(stderr, "Function stdin_send: wrong packet type\n");
723       exit(1);
724     }
725
726   if ( sizeof(struct ieee80211_frame)
727       + sizeof(struct GNUNET_MessageHeader) > sendsize)
728     {
729       fprintf(stderr, "Function stdin_send: packet too small\n");
730       exit(1);
731     }
732
733   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
734   u8aRadiotap[8] = header->rate;
735
736   switch (dev->drivertype)
737     {
738
739   case DT_MAC80211_RT:
740     memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
741     memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize);
742
743     wlanheader = write_pout->buf + sizeof(u8aRadiotap);
744     mac_set(wlanheader, dev);
745
746     sendsize += sizeof(u8aRadiotap);
747
748     break;
749   default:
750     break;
751     }
752
753   write_pout->size = sendsize;
754 }
755
756 static int
757 maketest(unsigned char * buf, struct Hardware_Infos * dev)
758 {
759   uint16_t * tmp16;
760   static uint16_t seqenz = 0;
761   static int first = 0;
762
763   const int rate = 11000000;
764   static const char
765       txt[] =
766           "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
767
768   unsigned char u8aRadiotap[] =
769     { 0x00, 0x00, // <-- radiotap version
770         0x00, 0x00, // <- radiotap header length
771         0x04, 0x80, 0x02, 0x00, // <-- bitmap
772         0x00, // <-- rate
773         0x00, // <-- padding for natural alignment
774         0x10, 0x00, // <-- TX flags
775         0x04 //retries
776       };
777
778   /*uint8_t u8aRadiotap[] =
779    {
780    0x00, 0x00, // <-- radiotap version
781    0x19, 0x00, // <- radiotap header length
782    0x6f, 0x08, 0x00, 0x00, // <-- bitmap
783    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
784    0x00, // <-- flags (Offset +0x10)
785    0x6c, // <-- rate (0ffset +0x11)
786    0x71, 0x09, 0xc0, 0x00, // <-- channel
787    0xde, // <-- antsignal
788    0x00, // <-- antnoise
789    0x01, // <-- antenna
790    };*/
791
792   u8aRadiotap[8] = (rate / 500000);
793   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
794
795   static struct ieee80211_frame u8aIeeeHeader;
796
797   uint8_t u8aIeeeHeader_def[] =
798     { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
799         //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
800         //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
801         0x00, 0x00, // Duration/ID
802
803         //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
804         0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
805         0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
806         //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
807         0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
808         0x10, 0x86, //Sequence Control
809       };
810   if (0 == first)
811     {
812       memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame));
813       memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6);
814       first = 1;
815     }
816
817   tmp16 = (uint16_t*) u8aIeeeHeader.i_dur;
818   *tmp16
819       = (uint16_t) htole16((sizeof(txt) + sizeof(struct ieee80211_frame) * 1000000) / rate + 290);
820   tmp16 = (uint16_t*) u8aIeeeHeader.i_seq;
821   *tmp16 = (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16(seqenz)
822       << IEEE80211_SEQ_SEQ_SHIFT);
823   seqenz++;
824
825   memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap));
826   memcpy(buf + sizeof(u8aRadiotap), &u8aIeeeHeader, sizeof(u8aIeeeHeader));
827   memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt));
828   return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt);
829
830 }
831
832 int
833 hardwaremode(int argc, char *argv[])
834 {
835
836   uid_t uid;
837   struct Hardware_Infos dev;
838   struct Radiotap_rx * rxinfo;
839   uint8_t * mac = dev.pl_mac;
840   int fdpin, fdpout;
841
842   struct GNUNET_MessageHeader * header;
843
844   signal(SIGINT, &sigfunc_hw);
845   signal(SIGTERM, &sigfunc_hw);
846
847   if (wlaninit(&dev, argv[1]))
848     {
849       return 1;
850     }
851
852   uid = getuid();
853   //if (0 != setresuid(uid, uid, uid))
854   //{
855   //  fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
856   /* not critical, continue anyway */
857   //}
858
859   unsigned char * datastart;
860   char readbuf[MAXLINE];
861   int readsize = 0;
862   struct sendbuf write_std;
863   write_std.size = 0;
864   write_std.pos = 0;
865
866   struct sendbuf write_pout;
867   write_pout.size = 0;
868   write_pout.pos = 0;
869
870   dev.write_pout = &write_pout;
871
872   int ret = 0;
873   int maxfd = 0;
874
875   fd_set rfds;
876   fd_set wfds;
877   struct timeval tv;
878   int retval;
879
880   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
881
882   fdpin = dev.fd_in;
883   fdpout = dev.fd_out;
884
885   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
886
887   //send mac first
888
889   write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac);
890
891   //wait
892   tv.tv_sec = 2;
893   tv.tv_usec = 0;
894   retval = select(0, NULL, NULL, NULL, &tv);
895
896   while (0 == closeprog)
897     {
898
899       //write_pout.size = maketest(write_pout.buf, &dev);
900       //tv.tv_sec = 2;
901       //tv.tv_usec = 0;
902       //select(0, NULL, NULL, NULL, &tv);
903
904       maxfd = 0;
905
906       //set timeout
907       tv.tv_sec = 5;
908       tv.tv_usec = 0;
909
910       FD_ZERO(&rfds);
911       // if output queue is empty
912       if (0 == write_pout.size)
913         {
914           FD_SET(STDIN_FILENO, &rfds);
915
916         }
917       if (0 == write_std.size)
918         {
919           FD_SET(fdpin, &rfds);
920           maxfd = fdpin;
921         }
922       FD_ZERO(&wfds);
923       // if there is something to write
924       if (0 < write_std.size)
925         {
926           FD_SET(STDOUT_FILENO, &wfds);
927           maxfd = MAX(maxfd, STDOUT_FILENO);
928         }
929
930       if (0 < write_pout.size)
931         {
932           FD_SET(fdpout, &wfds);
933           maxfd = MAX(maxfd, fdpout);
934         }
935
936       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
937
938       if (-1 == retval && EINTR == errno)
939         {
940           continue;
941         }
942       if (0 > retval)
943         {
944           fprintf(stderr, "select failed: %s\n", strerror(errno));
945           exit(1);
946         }
947
948       if (FD_ISSET(STDOUT_FILENO, &wfds))
949         {
950           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
951               write_std.size - write_std.pos);
952
953           if (0 > ret)
954             {
955               closeprog = 1;
956               fprintf(stderr, "Write ERROR to STDOUT\n");
957               goto end;
958             }
959           else
960             {
961               write_std.pos += ret;
962               // check if finished
963               if (write_std.pos == write_std.size)
964                 {
965                   write_std.pos = 0;
966                   write_std.size = 0;
967                 }
968             }
969         }
970
971       if (FD_ISSET(fdpout, &wfds))
972         {
973
974           ret = linux_write(&dev, write_pout.buf, write_pout.size);
975
976           if (0 > ret)
977             {
978               closeprog = 1;
979               fprintf(stderr, "Write ERROR to fdpout\n");
980             }
981           else
982             {
983               write_pout.pos += ret;
984               // check if finished
985               if (write_pout.pos != write_pout.size && ret != 0)
986                 {
987                   closeprog = 1;
988                   fprintf(stderr,
989                       "Write ERROR packet not in one piece send: %u, %u\n",
990                       write_pout.pos, write_pout.size);
991                 }
992               else if (write_pout.pos == write_pout.size)
993                 {
994                   write_pout.pos = 0;
995                   write_pout.size = 0;
996                 }
997
998             }
999         }
1000
1001       if (FD_ISSET(STDIN_FILENO, &rfds))
1002         {
1003           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
1004
1005           if (0 > readsize)
1006             {
1007               closeprog = 1;
1008               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
1009             }
1010           else if (0 < readsize)
1011             {
1012               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
1013                   GNUNET_NO, GNUNET_NO);
1014
1015             }
1016           else
1017             {
1018               //eof
1019               closeprog = 1;
1020             }
1021         }
1022
1023       if (FD_ISSET(fdpin, &rfds))
1024         {
1025           rxinfo = (struct Radiotap_rx *) (write_std.buf
1026               + sizeof(struct GNUNET_MessageHeader));
1027           datastart = (unsigned char *) write_std.buf
1028               + sizeof(struct Radiotap_rx)
1029               + sizeof(struct GNUNET_MessageHeader);
1030
1031           readsize = linux_read(&dev, datastart, sizeof(write_std.buf)
1032               - sizeof(struct Radiotap_rx)
1033               - sizeof(struct GNUNET_MessageHeader), rxinfo);
1034
1035           if (0 > readsize)
1036             {
1037               closeprog = 1;
1038               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
1039               closeprog = 1;
1040             }
1041           else if (0 < readsize)
1042             {
1043               if (1 == mac_test(datastart, &dev))
1044                 {
1045                   // mac wrong
1046                   write_std.pos = 0;
1047                   write_std.size = 0;
1048                 }
1049               else
1050                 {
1051                   header = (struct GNUNET_MessageHeader *) write_std.buf;
1052                   write_std.size = readsize
1053                       + sizeof(struct GNUNET_MessageHeader)
1054                       + sizeof(struct Radiotap_rx);
1055                   header->size = htons(write_std.size);
1056                   header->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1057                   fprintf(stderr, "Got packet with size: %u, size std %u\n",
1058                       readsize, write_std.size);
1059
1060                 }
1061             }
1062         }
1063
1064     }
1065
1066   GNUNET_SERVER_mst_destroy(stdin_mst);
1067   return 0;
1068
1069   end: GNUNET_SERVER_mst_destroy(stdin_mst);
1070   return 1;
1071
1072 }
1073
1074 int
1075 main(int argc, char *argv[])
1076 {
1077   int ret = 0;
1078   if (3 != argc)
1079     {
1080       fprintf(
1081           stderr,
1082           "This program must be started with the interface and the operating mode as argument.\n");
1083       usage();
1084       return 1;
1085     }
1086
1087   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
1088     {
1089
1090       ret = testmode(argc, argv);
1091     }
1092   else
1093     {
1094
1095       ret = hardwaremode(argc, argv);
1096     }
1097
1098   return ret;
1099   maketest(NULL, NULL);
1100 }
1101