indentation
[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 #include "wlan/helper_common.h"
86
87 #define ARPHRD_IEEE80211        801
88 #define ARPHRD_IEEE80211_PRISM  802
89 #define ARPHRD_IEEE80211_FULL   803
90
91 #define DEBUG 1
92
93 #define MAC_ADDR_SIZE 6
94
95 //Part taken from file ieee80211.h
96 /*-
97  * Copyright (c) 2001 Atsushi Onoe
98  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
99  * All rights reserved.
100  *
101  * Redistribution and use in source and binary forms, with or without
102  * modification, are permitted provided that the following conditions
103  * are met:
104  * 1. Redistributions of source code must retain the above copyright
105  *    notice, this list of conditions and the following disclaimer.
106  * 2. Redistributions in binary form must reproduce the above copyright
107  *    notice, this list of conditions and the following disclaimer in the
108  *    documentation and/or other materials provided with the distribution.
109  * 3. The name of the author may not be used to endorse or promote products
110  *    derived from this software without specific prior written permission.
111  *
112  * Alternatively, this software may be distributed under the terms of the
113  * GNU General Public License ("GPL") version 2 as published by the Free
114  * Software Foundation.
115  *
116  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
117  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
118  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
119  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
120  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
121  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
122  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
123  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
125  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126  *
127  * $FreeBSD: src/sys/net80211/ieee80211.h,v 1.12 2006/12/01 18:40:51 imp Exp $
128  */
129
130 #define IEEE80211_ADDR_LEN      6       /* size of 802.11 address */
131
132 /*
133  * generic definitions for IEEE 802.11 frames
134  */
135 struct ieee80211_frame
136 {
137   u_int8_t i_fc[2];
138   u_int8_t i_dur[2];
139   u_int8_t i_addr1[IEEE80211_ADDR_LEN];
140   u_int8_t i_addr2[IEEE80211_ADDR_LEN];
141   u_int8_t i_addr3[IEEE80211_ADDR_LEN];
142   u_int8_t i_seq[2];
143   /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
144   /* see below */
145 } GNUNET_PACKED;
146
147 // End taken part
148
149 struct Hardware_Infos
150 {
151
152   struct sendbuf write_pout;
153   int fd_raw;
154   int arptype_in;
155
156   /**
157    * Name of the interface, not necessarily 0-terminated (!).
158    */
159   char iface[IFNAMSIZ];
160   unsigned char pl_mac[MAC_ADDR_SIZE];
161 };
162
163 struct RadioTapheader
164 {
165   struct ieee80211_radiotap_header header;
166   u8 rate;
167   u8 pad1;
168   u16 txflags;
169 };
170
171 // FIXME: inline?
172 int
173 getChannelFromFrequency (int frequency);
174
175 // FIXME: make nice...
176 static unsigned long
177 calc_crc_osdep (unsigned char *buf, int len)
178 {
179   unsigned long crc = 0xFFFFFFFF;
180
181   for (; len > 0; len--, buf++)
182     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
183
184   return (~crc);
185 }
186
187 /* CRC checksum verification routine */
188
189 // FIXME: make nice...
190 // fixme doxigen
191 static int
192 check_crc_buf_osdep (unsigned char *buf, int len)
193 {
194   unsigned long crc;
195
196   if (0 > len)
197     return 0;
198
199   crc = calc_crc_osdep (buf, len);
200   buf += len;
201   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
202           ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
203 }
204
205
206 // FIXME: make nice...
207 //fixme doxigen
208 static int
209 linux_get_channel (struct Hardware_Infos *dev)
210 {
211   struct iwreq wrq;
212   int fd, frequency;
213   int chan = 0;
214
215   memset (&wrq, 0, sizeof (struct iwreq));
216
217   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
218
219   fd = dev->fd_raw;
220   if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
221     return (-1);
222
223   frequency = wrq.u.freq.m;
224   if (100000000 < frequency)
225     frequency /= 100000;
226   else if (1000000 < frequency)
227     frequency /= 1000;
228
229   if (1000 < frequency)
230     chan = getChannelFromFrequency (frequency);
231   else
232     chan = frequency;
233
234   return chan;
235 }
236
237
238 // FIXME: make nice...
239 //FIXME doxigen
240 static ssize_t
241 linux_read (struct Hardware_Infos *dev, unsigned char *buf,     /* FIXME: void*? */
242             size_t buf_size, struct Radiotap_rx *ri)
243 {
244   unsigned char tmpbuf[buf_size];
245   ssize_t caplen;
246   int n, got_signal, got_noise, got_channel, fcs_removed;
247
248   n = got_signal = got_noise = got_channel = fcs_removed = 0;
249
250   caplen = read (dev->fd_raw, tmpbuf, buf_size);
251   if (0 > caplen)
252   {
253     if (EAGAIN == errno)
254       return 0;
255     fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
256     return -1;
257   }
258
259   memset (buf, 0, buf_size);
260   memset (ri, 0, sizeof (*ri));
261
262   switch (dev->arptype_in)
263   {
264   case ARPHRD_IEEE80211_PRISM:
265   {
266     /* skip the prism header */
267     if (tmpbuf[7] == 0x40)
268     {
269       /* prism54 uses a different format */
270       ri->ri_power = tmpbuf[0x33];
271       ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
272       ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
273       got_signal = 1;
274       got_noise = 1;
275       n = 0x40;
276     }
277     else
278     {
279       ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48);
280       ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
281       ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
282       ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
283       ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
284       got_channel = 1;
285       got_signal = 1;
286       got_noise = 1;
287       n = *(int *) (tmpbuf + 4);
288     }
289
290     if (n < 8 || n >= caplen)
291       return (0);
292   }
293     break;
294
295   case ARPHRD_IEEE80211_FULL:
296   {
297     struct ieee80211_radiotap_iterator iterator;
298     struct ieee80211_radiotap_header *rthdr;
299
300     rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
301
302     if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
303       return (0);
304
305     /* go through the radiotap arguments we have been given
306      * by the driver
307      */
308
309     while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
310     {
311
312       switch (iterator.this_arg_index)
313       {
314
315       case IEEE80211_RADIOTAP_TSFT:
316         ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg));
317         break;
318
319       case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
320         if (!got_signal)
321         {
322           if (*iterator.this_arg < 127)
323             ri->ri_power = *iterator.this_arg;
324           else
325             ri->ri_power = *iterator.this_arg - 255;
326
327           got_signal = 1;
328         }
329         break;
330
331       case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
332         if (!got_signal)
333         {
334           if (*iterator.this_arg < 127)
335             ri->ri_power = *iterator.this_arg;
336           else
337             ri->ri_power = *iterator.this_arg - 255;
338
339           got_signal = 1;
340         }
341         break;
342
343       case IEEE80211_RADIOTAP_DBM_ANTNOISE:
344         if (!got_noise)
345         {
346           if (*iterator.this_arg < 127)
347             ri->ri_noise = *iterator.this_arg;
348           else
349             ri->ri_noise = *iterator.this_arg - 255;
350
351           got_noise = 1;
352         }
353         break;
354
355       case IEEE80211_RADIOTAP_DB_ANTNOISE:
356         if (!got_noise)
357         {
358           if (*iterator.this_arg < 127)
359             ri->ri_noise = *iterator.this_arg;
360           else
361             ri->ri_noise = *iterator.this_arg - 255;
362
363           got_noise = 1;
364         }
365         break;
366
367       case IEEE80211_RADIOTAP_ANTENNA:
368         ri->ri_antenna = *iterator.this_arg;
369         break;
370
371       case IEEE80211_RADIOTAP_CHANNEL:
372         ri->ri_channel = *iterator.this_arg;
373         got_channel = 1;
374         break;
375
376       case IEEE80211_RADIOTAP_RATE:
377         ri->ri_rate = (*iterator.this_arg) * 500000;
378         break;
379
380       case IEEE80211_RADIOTAP_FLAGS:
381         /* is the CRC visible at the end?
382          * remove
383          */
384         if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
385         {
386           fcs_removed = 1;
387           caplen -= 4;
388         }
389
390         if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
391           return (0);
392
393         break;
394       }
395     }
396     n = le16_to_cpu (rthdr->it_len);
397     if (n <= 0 || n >= caplen)
398       return 0;
399   }
400     break;
401   case ARPHRD_IEEE80211:
402     /* do nothing? */
403     break;
404   default:
405     errno = ENOTSUP;
406     return -1;
407   }
408
409   caplen -= n;
410
411   //detect fcs at the end, even if the flag wasn't set and remove it
412   if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
413   {
414     caplen -= 4;
415   }
416   memcpy (buf, tmpbuf + n, caplen);
417   if (!got_channel)
418     ri->ri_channel = linux_get_channel (dev);
419
420   return caplen;
421 }
422
423 //FIXME doxigen
424 /**
425  * @return 0 on success
426  */
427 static int
428 openraw (struct Hardware_Infos *dev)
429 {
430   struct ifreq ifr;
431   struct iwreq wrq;
432   struct packet_mreq mr;
433   struct sockaddr_ll sll;
434
435   /* find the interface index */
436   memset (&ifr, 0, sizeof (ifr));
437   strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
438   if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
439   {
440     fprintf (stderr,
441              "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
442              IFNAMSIZ, dev->iface, strerror (errno));
443     return 1;
444   }
445
446   /* lookup the hardware type */
447   memset (&sll, 0, sizeof (sll));
448   sll.sll_family = AF_PACKET;
449   sll.sll_ifindex = ifr.ifr_ifindex;
450   sll.sll_protocol = htons (ETH_P_ALL);
451   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
452   {
453     fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
454              IFNAMSIZ, dev->iface, strerror (errno));
455     return 1;
456   }
457
458   /* lookup iw mode */
459   memset (&wrq, 0, sizeof (struct iwreq));
460   strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
461   if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
462   {
463     /* most probably not supported (ie for rtap ipw interface) *
464      * so just assume its correctly set...                     */
465     wrq.u.mode = IW_MODE_MONITOR;
466   }
467
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       (wrq.u.mode != IW_MODE_MONITOR))
472   {
473     fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
474              IFNAMSIZ, dev->iface);
475     return 1;
476   }
477
478   /* Is interface st to up, broadcast & running ? */
479   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
480   {
481     /* Bring interface up */
482     ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
483
484     if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
485     {
486       fprintf (stderr,
487                "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
488                IFNAMSIZ, dev->iface, strerror (errno));
489       return 1;
490     }
491   }
492
493   /* bind the raw socket to the interface */
494   if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
495   {
496     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
497              dev->iface, strerror (errno));
498     return 1;
499   }
500
501   /* lookup the hardware type */
502   if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
503   {
504     fprintf (stderr,
505              "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
506              IFNAMSIZ, dev->iface, strerror (errno));
507     return 1;
508   }
509
510   memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
511   dev->arptype_in = ifr.ifr_hwaddr.sa_family;
512   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
513       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
514       (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
515   {
516     fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
517              ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
518     return 1;
519   }
520
521   /* enable promiscuous mode */
522   memset (&mr, 0, sizeof (mr));
523   mr.mr_ifindex = sll.sll_ifindex;
524   mr.mr_type = PACKET_MR_PROMISC;
525   if (0 !=
526       setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
527                   sizeof (mr)))
528   {
529     fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
530              IFNAMSIZ, dev->iface);
531     return 1;
532   }
533
534   return 0;
535 }
536
537 /**
538  * @return 0 on success
539  */
540 static int
541 wlaninit (struct Hardware_Infos *dev, const char *iface)
542 {
543   char strbuf[512];
544   struct stat sbuf;
545   int ret;
546
547   dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
548   if (0 > dev->fd_raw)
549   {
550     fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
551     return 1;
552   }
553   if (dev->fd_raw >= FD_SETSIZE)
554   {
555     fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
556              dev->fd_raw, FD_SETSIZE);
557     close (dev->fd_raw);
558     return 1;
559   }
560
561   /* mac80211 stack detection */
562   ret =
563       snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
564                 iface);
565   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
566   {
567     fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
568     close (dev->fd_raw);
569     return 1;
570   }
571   strncpy (dev->iface, iface, IFNAMSIZ);
572   if (0 != openraw (dev))
573   {
574     close (dev->fd_raw);
575     return 1;
576   }
577   return 0;
578 }
579
580
581 /**
582  * Function to test incoming packets mac for being our own.
583  *
584  * @param u8aIeeeHeader buffer of the packet
585  * @param dev the Hardware_Infos struct
586  * @return 0 if mac belongs to us, 1 if mac is for another target
587  */
588 static int
589 mac_test (const struct ieee80211_frame *u8aIeeeHeader,
590           const struct Hardware_Infos *dev)
591 {
592   if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
593     return 1;
594   if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE))
595     return 0;
596   if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
597     return 0;
598   return 1;
599 }
600
601
602 /**
603  * function to set the wlan header to make attacks more difficult
604  * @param u8aIeeeHeader pointer to the header of the packet
605  * @param dev pointer to the Hardware_Infos struct
606  */
607 static void
608 mac_set (struct ieee80211_frame *u8aIeeeHeader,
609          const struct Hardware_Infos *dev)
610 {
611   u8aIeeeHeader->i_fc[0] = 0x08;
612   u8aIeeeHeader->i_fc[1] = 0x00;
613   memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
614   memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
615
616 }
617
618 //FIXME: doxigen
619 static void
620 stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
621 {
622   struct Hardware_Infos *dev = cls;
623   struct sendbuf *write_pout = &dev->write_pout;
624   struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
625   struct ieee80211_frame *wlanheader;
626   size_t sendsize;
627
628   // struct? // FIXME: make nice...
629   struct RadioTapheader rtheader;
630
631   rtheader.header.it_version = 0;
632   rtheader.header.it_len = htole16 (0x0c);
633   rtheader.header.it_present = htole32 (0x00008004);
634   rtheader.rate = 0x00;
635   rtheader.txflags =
636       htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
637
638   /*  { 0x00, 0x00, <-- radiotap version
639    * 0x0c, 0x00, <- radiotap header length
640    * 0x04, 0x80, 0x00, 0x00,  <-- bitmap
641    * 0x00,  <-- rate
642    * 0x00,  <-- padding for natural alignment
643    * 0x18, 0x00,  <-- TX flags
644    * }; */
645
646   sendsize = ntohs (hdr->size);
647   if (sendsize <
648       sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
649   {
650     fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
651     exit (1);
652   }
653   sendsize -=
654       sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
655
656   if (MAXLINE < sendsize)
657   {
658     fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
659     exit (1);
660   }
661   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
662   {
663     fprintf (stderr, "Function stdin_send: wrong packet type\n");
664     exit (1);
665   }
666
667   rtheader.header.it_len = htole16 (sizeof (rtheader));
668   rtheader.rate = header->rate;
669   memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
670   memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
671   /* payload contains MAC address, but we don't trust it, so we'll
672    * overwrite it with OUR MAC address again to prevent mischief */
673   wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
674   mac_set (wlanheader, dev);
675   write_pout->size = sendsize + sizeof (rtheader);
676 }
677
678 #if 0
679 static int
680 maketest (unsigned char *buf, struct Hardware_Infos *dev)
681 {
682   uint16_t *tmp16;
683   static uint16_t seqenz = 0;
684   static int first = 0;
685
686   const int rate = 11000000;
687   static const char txt[] =
688       "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
689
690   unsigned char u8aRadiotap[] = { 0x00, 0x00,   // <-- radiotap version
691     0x00, 0x00,                 // <- radiotap header length
692     0x04, 0x80, 0x02, 0x00,     // <-- bitmap
693     0x00,                       // <-- rate
694     0x00,                       // <-- padding for natural alignment
695     0x10, 0x00,                 // <-- TX flags
696     0x04                        //retries
697   };
698
699   /*uint8_t u8aRadiotap[] =
700    * {
701    * 0x00, 0x00, // <-- radiotap version
702    * 0x19, 0x00, // <- radiotap header length
703    * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
704    * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
705    * 0x00, // <-- flags (Offset +0x10)
706    * 0x6c, // <-- rate (0ffset +0x11)
707    * 0x71, 0x09, 0xc0, 0x00, // <-- channel
708    * 0xde, // <-- antsignal
709    * 0x00, // <-- antnoise
710    * 0x01, // <-- antenna
711    * }; */
712
713   u8aRadiotap[8] = (rate / 500000);
714   u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
715
716   static struct ieee80211_frame u8aIeeeHeader;
717
718   uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00,   // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
719     //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
720     //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
721     0x00, 0x00,                 // Duration/ID
722
723     //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
724     0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
725     0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
726     //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
727     0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
728     0x10, 0x86,                 //Sequence Control
729   };
730   if (0 == first)
731   {
732     memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
733     memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
734     first = 1;
735   }
736
737   tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
738   *tmp16 =
739       (uint16_t)
740       htole16 ((sizeof (txt) +
741                 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
742   tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
743   *tmp16 =
744       (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
745                                             IEEE80211_SEQ_SEQ_SHIFT);
746   seqenz++;
747
748   memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
749   memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
750   memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
751           sizeof (txt));
752   return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
753
754 }
755 #endif
756
757
758 /**
759  * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
760  * @param buffer pointer to buffer for the message
761  * @param mac pointer to the mac address
762  * @return number of bytes written
763  */
764 // FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file)
765 /*
766 static int
767 send_mac_to_plugin (char *buffer, struct MacAddress * mac)
768 {
769   struct Wlan_Helper_Control_Message macmsg;
770
771   macmsg.hdr.size = htons (sizeof (struct Wlan_Helper_Control_Message));
772   macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
773   memcpy (macmsg.mac, mac, sizeof (struct MacAddress));
774   memcpy (buffer, &macmsg, sizeof (struct Wlan_Helper_Control_Message));
775   return sizeof (struct Wlan_Helper_Control_Message);
776 }
777 */
778
779 //FIXME: doxigen
780 static int
781 hardwaremode (int argc, char *argv[])
782 {
783   uid_t uid;
784   struct Hardware_Infos dev;
785   char readbuf[MAXLINE];
786   struct sendbuf write_std;
787   ssize_t ret;
788   int maxfd;
789   fd_set rfds;
790   fd_set wfds;
791   int retval;
792   int stdin_open;
793   struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
794
795   if (0 != wlaninit (&dev, argv[1]))
796     return 1;
797   uid = getuid ();
798   if (0 != setresuid (uid, uid, uid))
799   {
800     fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
801     /* not critical, continue anyway */
802   }
803
804   dev.write_pout.size = 0;
805   dev.write_pout.pos = 0;
806   stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
807
808   /* send mac to STDOUT first */
809   write_std.pos = 0;
810   write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac);
811   stdin_open = 1;
812
813   while (1)
814   {
815     maxfd = -1;
816     FD_ZERO (&rfds);
817     if ((0 == dev.write_pout.size) && (1 == stdin_open))
818     {
819       FD_SET (STDIN_FILENO, &rfds);
820       maxfd = MAX (maxfd, STDIN_FILENO);
821     }
822     if (0 == write_std.size)
823     {
824       FD_SET (dev.fd_raw, &rfds);
825       maxfd = MAX (maxfd, dev.fd_raw);
826     }
827     FD_ZERO (&wfds);
828     if (0 < write_std.size)
829     {
830       FD_SET (STDOUT_FILENO, &wfds);
831       maxfd = MAX (maxfd, STDOUT_FILENO);
832     }
833     if (0 < dev.write_pout.size)
834     {
835       FD_SET (dev.fd_raw, &wfds);
836       maxfd = MAX (maxfd, dev.fd_raw);
837     }
838     retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
839     if ((-1 == retval) && (EINTR == errno))
840       continue;
841     if (0 > retval)
842     {
843       fprintf (stderr, "select failed: %s\n", strerror (errno));
844       break;
845     }
846
847     if (FD_ISSET (STDOUT_FILENO, &wfds))
848     {
849       ret =
850           write (STDOUT_FILENO, write_std.buf + write_std.pos,
851                  write_std.size - write_std.pos);
852       if (0 > ret)
853       {
854         fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
855         break;
856       }
857       write_std.pos += ret;
858       if (write_std.pos == write_std.size)
859       {
860         write_std.pos = 0;
861         write_std.size = 0;
862       }
863     }
864
865     if (FD_ISSET (dev.fd_raw, &wfds))
866     {
867       ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
868       if (0 > ret)
869       {
870         fprintf (stderr,
871                  "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n",
872                  __LINE__, strerror (errno), dev.write_pout.size);
873         break;
874       }
875       dev.write_pout.pos += ret;
876       if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
877       {
878         fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n",
879                  __LINE__, dev.write_pout.pos, dev.write_pout.size);
880         break;
881       }
882       if (dev.write_pout.pos == dev.write_pout.size)
883       {
884         dev.write_pout.pos = 0;
885         dev.write_pout.size = 0;
886       }
887     }
888
889     if (FD_ISSET (STDIN_FILENO, &rfds))
890     {
891       ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
892       if (0 > ret)
893       {
894         fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
895         break;
896       }
897       if (0 == ret)
898       {
899         /* stop reading... */
900         stdin_open = 0;
901       }
902       GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
903                                  GNUNET_NO);
904     }
905
906     if (FD_ISSET (dev.fd_raw, &rfds))
907     {
908       struct GNUNET_MessageHeader *header;
909       struct Radiotap_rx *rxinfo;
910       struct ieee80211_frame *datastart;
911
912       header = (struct GNUNET_MessageHeader *) write_std.buf;
913       rxinfo = (struct Radiotap_rx *) &header[1];
914       datastart = (struct ieee80211_frame *) &rxinfo[1];
915       ret =
916           linux_read (&dev, (unsigned char *) datastart,
917                       sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
918                       sizeof (struct GNUNET_MessageHeader), rxinfo);
919       if (0 > ret)
920       {
921         fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
922         break;
923       }
924       if ((0 < ret) && (0 == mac_test (datastart, &dev)))
925       {
926         write_std.size =
927             ret + sizeof (struct GNUNET_MessageHeader) +
928             sizeof (struct Radiotap_rx);
929         header->size = htons (write_std.size);
930         header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
931       }
932     }
933
934   }
935   /* Error handling, try to clean up a bit at least */
936   GNUNET_SERVER_mst_destroy (stdin_mst);
937   close (dev.fd_raw);
938   return 1;
939 }
940
941 int
942 main (int argc, char *argv[])
943 {
944   if (2 != argc)
945   {
946     fprintf (stderr,
947              "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
948              __TIMESTAMP__);
949     fprintf (stderr, "Usage: interface-name\n" "\n");
950     return 1;
951   }
952   return hardwaremode (argc, argv);
953 }
954
955 /*
956    *  Copyright (c) 2008, Thomas d'Otreppe
957    *
958    *  Common OSdep stuff
959    *
960    *  This program is free software; you can redistribute it and/or modify
961    *  it under the terms of the GNU General Public License as published by
962    *  the Free Software Foundation; either version 2 of the License, or
963    *  (at your option) any later version.
964    *
965    *  This program is distributed in the hope that it will be useful,
966    *  but WITHOUT ANY WARRANTY; without even the implied warranty of
967    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
968    *  GNU General Public License for more details.
969    *
970    *  You should have received a copy of the GNU General Public License
971    *  along with this program; if not, write to the Free Software
972    *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
973    */
974
975 /**
976  * Return the frequency in Mhz from a channel number
977  */
978 int
979 getFrequencyFromChannel (int channel)
980 {
981   static int frequencies[] = {
982     -1,                         // No channel 0
983     2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467,
984     2472, 2484,
985     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Nothing from channel 15 to 34 (exclusive)
986     5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225,
987     5230, 5235, 5240, 5245,
988     5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305,
989     5310, 5315, 5320, 5325,
990     5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385,
991     5390, 5395, 5400, 5405,
992     5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465,
993     5470, 5475, 5480, 5485,
994     5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545,
995     5550, 5555, 5560, 5565,
996     5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625,
997     5630, 5635, 5640, 5645,
998     5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705,
999     5710, 5715, 5720, 5725,
1000     5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785,
1001     5790, 5795, 5800, 5805,
1002     5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865,
1003     5870, 5875, 5880, 5885,
1004     5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945,
1005     5950, 5955, 5960, 5965,
1006     5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025,
1007     6030, 6035, 6040, 6045,
1008     6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100
1009   };
1010
1011   return (channel > 0 && channel <= 221) ? frequencies[channel] : -1;
1012 }
1013
1014 /**
1015  * Return the channel from the frequency (in Mhz)
1016  */
1017 int
1018 getChannelFromFrequency (int frequency)
1019 {
1020   if (frequency >= 2412 && frequency <= 2472)
1021     return (frequency - 2407) / 5;
1022   else if (frequency == 2484)
1023     return 14;
1024   else if (frequency >= 5000 && frequency <= 6100)
1025     return (frequency - 5000) / 5;
1026   else
1027     return -1;
1028 }