wlan helper should work now for loopback, test configurations changed accordingly
[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
32 #include "platform.h"
33 #include "gnunet_constants.h"
34 #include "gnunet_os_lib.h"
35 #include "gnunet_transport_plugin.h"
36 #include "transport.h"
37 #include "gnunet_util_lib.h"
38 #include "plugin_transport_wlan.h"
39 #include "gnunet_common.h"
40 #include "gnunet-transport-wlan-helper.h"
41 #include "ieee80211_radiotap.h"
42 #include <pcap.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <sys/stat.h>
46
47
48
49
50
51 //#include "radiotap.h"
52
53 // mac of this node
54 char mac[] =
55   { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 };
56
57 /* wifi bitrate to use in 500kHz units */
58
59 static const u8 u8aRatesToUse[] = {
60
61         54*2,
62         48*2,
63         36*2,
64         24*2,
65         18*2,
66         12*2,
67         9*2,
68         11*2,
69         11, // 5.5
70         2*2,
71         1*2
72 };
73
74 #define OFFSET_FLAGS 0x10
75 #define OFFSET_RATE 0x11
76
77 // this is where we store a summary of the
78 // information from the radiotap header
79
80 typedef struct  {
81         int m_nChannel;
82         int m_nChannelFlags;
83         int m_nRate;
84         int m_nAntenna;
85         int m_nRadiotapFlags;
86 } __attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
87
88 void
89 Dump(u8 * pu8, int nLength)
90 {
91         char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
92         unsigned char baaLast[2][16];
93         uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
94
95         buf = szBuf;
96         szChar[0] = '\0';
97
98         for (n = 0; n < nLength; n++) {
99                 baaLast[(nLine&1)^1][n&0xf] = pu8[n];
100                 if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
101                         szChar[n&0xf] = '.';
102                 else
103                         szChar[n&0xf] = pu8[n];
104                 szChar[(n&0xf)+1] = '\0';
105                 nPos += sprintf(&sz[nPos], "%02X ",
106                         baaLast[(nLine&1)^1][n&0xf]);
107                 if ((n&15) != 15)
108                         continue;
109                 if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) {
110                         nSameCount++;
111                 } else {
112                         if (nSameCount)
113                                 buf += sprintf(buf, "(repeated %d times)\n",
114                                         nSameCount);
115                         buf += sprintf(buf, "%04x: %s %s\n",
116                                 nStart, sz, szChar);
117                         nSameCount = 0;
118                         printf("%s", szBuf);
119                         buf = szBuf;
120                 }
121                 nPos = 0; nStart = n+1; nLine++;
122                 fFirst = 0; sz[0] = '\0'; szChar[0] = '\0';
123         }
124         if (nSameCount)
125                 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
126
127         buf += sprintf(buf, "%04x: %s", nStart, sz);
128         if (n & 0xf) {
129                 *buf++ = ' ';
130                 while (n & 0xf) {
131                         buf += sprintf(buf, "   ");
132                         n++;
133                 }
134         }
135         buf += sprintf(buf, "%s\n", szChar);
136         printf("%s", szBuf);
137 }
138
139
140 void
141 usage()
142 {
143         printf(
144             "Usage: wlan-hwd [options] <interface>\n\nOptions\n"
145             "-f/--fcs           Mark as having FCS (CRC) already\n"
146             "                   (pkt ends with 4 x sacrificial - chars)\n"
147             "Example:\n"
148             "  echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
149             "  iwconfig mon0 mode monitor\n"
150             "  ifconfig mon0 up\n"
151             "  wlan-hwd mon0        Spam down mon0 with\n"
152             "                       radiotap header first\n"
153             "\n");
154         exit(1);
155 }
156
157 int flagHelp = 0, flagMarkWithFCS = 0;
158 int flagVerbose = 0;
159
160
161 /*
162  * Radiotap parser
163  *
164  * Copyright 2007               Andy Green <andy@warmcat.com>
165  */
166
167 /**
168  * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
169  * @param iterator: radiotap_iterator to initialize
170  * @param radiotap_header: radiotap header to parse
171  * @param max_length: total length we can parse into (eg, whole packet length)
172  *
173  * @return 0 or a negative error code if there is a problem.
174  *
175  * This function initializes an opaque iterator struct which can then
176  * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
177  * argument which is present in the header.  It knows about extended
178  * present headers and handles them.
179  *
180  * How to use:
181  * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
182  * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
183  * checking for a good 0 return code.  Then loop calling
184  * __ieee80211_radiotap_iterator_next()... it returns either 0,
185  * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
186  * The iterator's this_arg member points to the start of the argument
187  * associated with the current argument index that is present, which can be
188  * found in the iterator's this_arg_index member.  This arg index corresponds
189  * to the IEEE80211_RADIOTAP_... defines.
190  *
191  * Radiotap header length:
192  * You can find the CPU-endian total radiotap header length in
193  * iterator->max_length after executing ieee80211_radiotap_iterator_init()
194  * successfully.
195  *
196  * Example code:
197  * See Documentation/networking/radiotap-headers.txt
198  */
199
200 int ieee80211_radiotap_iterator_init(
201     struct ieee80211_radiotap_iterator *iterator,
202     struct ieee80211_radiotap_header *radiotap_header,
203     int max_length)
204 {
205         /* Linux only supports version 0 radiotap format */
206         if (radiotap_header->it_version)
207                 return -EINVAL;
208
209         /* sanity check for allowed length and radiotap length field */
210         if (max_length < le16_to_cpu(radiotap_header->it_len))
211                 return -EINVAL;
212
213         iterator->rtheader = radiotap_header;
214         iterator->max_length = le16_to_cpu(radiotap_header->it_len);
215         iterator->arg_index = 0;
216         iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present);
217         iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
218         iterator->this_arg = 0;
219
220         /* find payload start allowing for extended bitmap(s) */
221
222         if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
223                 while (le32_to_cpu(*((u32 *)iterator->arg)) &
224                                    (1<<IEEE80211_RADIOTAP_EXT)) {
225                         iterator->arg += sizeof(u32);
226
227                         /*
228                          * check for insanity where the present bitmaps
229                          * keep claiming to extend up to or even beyond the
230                          * stated radiotap header length
231                          */
232
233                         if (((ulong)iterator->arg -
234                              (ulong)iterator->rtheader) > iterator->max_length)
235                                 return -EINVAL;
236                 }
237
238                 iterator->arg += sizeof(u32);
239
240                 /*
241                  * no need to check again for blowing past stated radiotap
242                  * header length, because ieee80211_radiotap_iterator_next
243                  * checks it before it is dereferenced
244                  */
245         }
246
247         /* we are all initialized happily */
248
249         return 0;
250 }
251
252
253 /**
254  * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
255  * @param iterator: radiotap_iterator to move to next arg (if any)
256  *
257  * @return 0 if there is an argument to handle,
258  * -ENOENT if there are no more args or -EINVAL
259  * if there is something else wrong.
260  *
261  * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
262  * in this_arg_index and sets this_arg to point to the
263  * payload for the field.  It takes care of alignment handling and extended
264  * present fields.  this_arg can be changed by the caller (eg,
265  * incremented to move inside a compound argument like
266  * IEEE80211_RADIOTAP_CHANNEL).  The args pointed to are in
267  * little-endian format whatever the endianess of your CPU.
268  */
269
270 int ieee80211_radiotap_iterator_next(
271     struct ieee80211_radiotap_iterator *iterator)
272 {
273
274         /*
275          * small length lookup table for all radiotap types we heard of
276          * starting from b0 in the bitmap, so we can walk the payload
277          * area of the radiotap header
278          *
279          * There is a requirement to pad args, so that args
280          * of a given length must begin at a boundary of that length
281          * -- but note that compound args are allowed (eg, 2 x u16
282          * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
283          * a reliable indicator of alignment requirement.
284          *
285          * upper nybble: content alignment for arg
286          * lower nybble: content length for arg
287          */
288
289         static const u8 rt_sizes[] = {
290                 [IEEE80211_RADIOTAP_TSFT] = 0x88,
291                 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
292                 [IEEE80211_RADIOTAP_RATE] = 0x11,
293                 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
294                 [IEEE80211_RADIOTAP_FHSS] = 0x22,
295                 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
296                 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
297                 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
298                 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
299                 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
300                 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
301                 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
302                 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
303                 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11
304                 /*
305                  * add more here as they are defined in
306                  * include/net/ieee80211_radiotap.h
307                  */
308         };
309
310         /*
311          * for every radiotap entry we can at
312          * least skip (by knowing the length)...
313          */
314
315         while (iterator->arg_index < sizeof(rt_sizes)) {
316                 int hit = 0;
317                 int pad;
318
319                 if (!(iterator->bitmap_shifter & 1))
320                         goto next_entry; /* arg not present */
321
322                 /*
323                  * arg is present, account for alignment padding
324                  *  8-bit args can be at any alignment
325                  * 16-bit args must start on 16-bit boundary
326                  * 32-bit args must start on 32-bit boundary
327                  * 64-bit args must start on 64-bit boundary
328                  *
329                  * note that total arg size can differ from alignment of
330                  * elements inside arg, so we use upper nybble of length
331                  * table to base alignment on
332                  *
333                  * also note: these alignments are ** relative to the
334                  * start of the radiotap header **.  There is no guarantee
335                  * that the radiotap header itself is aligned on any
336                  * kind of boundary.
337                  */
338
339                 pad = (((ulong)iterator->arg) -
340                         ((ulong)iterator->rtheader)) &
341                         ((rt_sizes[iterator->arg_index] >> 4) - 1);
342
343                 if (pad)
344                         iterator->arg_index +=
345                                 (rt_sizes[iterator->arg_index] >> 4) - pad;
346
347                 /*
348                  * this is what we will return to user, but we need to
349                  * move on first so next call has something fresh to test
350                  */
351                 iterator->this_arg_index = iterator->arg_index;
352                 iterator->this_arg = iterator->arg;
353                 hit = 1;
354
355                 /* internally move on the size of this arg */
356                 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
357
358                 /*
359                  * check for insanity where we are given a bitmap that
360                  * claims to have more arg content than the length of the
361                  * radiotap section.  We will normally end up equalling this
362                  * max_length on the last arg, never exceeding it.
363                  */
364
365                 if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
366                     iterator->max_length)
367                         return -EINVAL;
368
369         next_entry:
370                 iterator->arg_index++;
371                 if (unlikely((iterator->arg_index & 31) == 0)) {
372                         /* completed current u32 bitmap */
373                         if (iterator->bitmap_shifter & 1) {
374                                 /* b31 was set, there is more */
375                                 /* move to next u32 bitmap */
376                                 iterator->bitmap_shifter =
377                                     le32_to_cpu(*iterator->next_bitmap);
378                                 iterator->next_bitmap++;
379                         } else {
380                                 /* no more bitmaps: end */
381                                 iterator->arg_index = sizeof(rt_sizes);
382                         }
383                 } else { /* just try the next bit */
384                         iterator->bitmap_shifter >>= 1;
385                 }
386
387                 /* if we found a valid arg earlier, return it now */
388                 if (hit)
389                         return 0;
390         }
391
392         /* we don't know how to handle any more args, we're done */
393         return -ENOENT;
394 }
395
396 #define FIFO_FILE1       "/tmp/MYFIFOin"
397 #define FIFO_FILE2       "/tmp/MYFIFOout"
398 #define MAXLINE         20
399
400 static int first;
401 static int closeprog;
402
403 static void 
404 sigfunc(int sig)
405 {
406   closeprog = 1;  
407   unlink(FIFO_FILE1);
408   unlink(FIFO_FILE2);
409 }
410
411 struct sendbuf {
412   int pos;
413   int size;
414   char buf[MAXLINE * 2];
415 };
416
417 static void
418 stdin_send (void *cls,
419                       void *client,
420                       const struct GNUNET_MessageHeader *hdr)
421 {
422   struct sendbuf *write_pout = cls;
423   int sendsize = ntohs(hdr->size) - sizeof(struct RadiotapHeader) ;
424   struct GNUNET_MessageHeader newheader;
425
426   GNUNET_assert(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA == ntohs(hdr->type));
427   GNUNET_assert (sendsize + write_pout->size < MAXLINE *2);
428
429
430   newheader.size = htons(sendsize);
431   newheader.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
432
433
434   memcpy(write_pout->buf + write_pout->size, &newheader, sizeof(struct GNUNET_MessageHeader));
435   write_pout->size += sizeof(struct GNUNET_MessageHeader);
436
437   memcpy(write_pout->buf + write_pout->size, hdr + sizeof(struct RadiotapHeader) + sizeof(struct GNUNET_MessageHeader), sizeof(struct GNUNET_MessageHeader));
438   write_pout->size += sendsize;
439 }
440
441 static void
442 file_in_send (void *cls,
443                       void *client,
444                       const struct GNUNET_MessageHeader *hdr)
445 {
446   struct sendbuf * write_std = cls;
447   int sendsize = ntohs(hdr->size);
448
449   GNUNET_assert(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA == ntohs(hdr->type));
450   GNUNET_assert (sendsize + write_std->size < MAXLINE *2);
451
452   memcpy(write_std->buf + write_std->size, hdr, sendsize);
453   write_std->size += sendsize;
454 }
455
456 int
457 testmode(int argc, char *argv[])
458 {
459   struct stat st;
460   int erg;
461
462   FILE *fpin;
463   FILE *fpout;
464
465   int fdpin;
466   int fdpout;
467
468   //make the fifos if needed
469   if (0 != stat(FIFO_FILE1, &st))
470     {
471       if (0 == stat(FIFO_FILE2, &st))
472         {
473         fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not");
474           exit(1);
475         }
476
477       umask(0);
478       erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0);
479       erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
480
481     }
482   else
483     {
484
485       if (0 != stat(FIFO_FILE2, &st))
486         {
487         fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not");
488           exit(1);
489         }
490
491     }
492
493   if (strstr(argv[2], "1"))
494     {
495       //fprintf(stderr, "First\n");
496       first = 1;
497       fpin = fopen(FIFO_FILE1, "r");
498       if (NULL == fpin)
499         {
500         fprintf(stderr, "fopen of read FIFO_FILE1");
501           exit(1);
502         }
503       if (NULL == (fpout = fopen(FIFO_FILE2, "w")))
504         {
505         fprintf(stderr, "fopen of write FIFO_FILE2");
506           exit(1);
507         }
508
509     }
510   else
511     {
512       first = 0;
513       //fprintf(stderr, "Second\n");
514       if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
515         {
516         fprintf(stderr, "fopen of write FIFO_FILE1");
517           exit(1);
518         }
519       if (NULL == (fpin = fopen(FIFO_FILE2, "r")))
520         {
521         fprintf(stderr, "fopen of read FIFO_FILE2");
522           exit(1);
523         }
524
525     }
526
527   fdpin = fileno(fpin);
528   if (fdpin >= FD_SETSIZE)
529     {
530       fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin,
531           (unsigned int) FD_SETSIZE);
532       close(fdpin);
533       return -1;
534     }
535
536   fdpout = fileno(fpout);
537   if (fdpout >= FD_SETSIZE)
538     {
539       fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout,
540           (unsigned int) FD_SETSIZE);
541       close(fdpout);
542       return -1;
543
544     }
545
546   signal(SIGINT, &sigfunc);
547   signal(SIGTERM, &sigfunc);
548
549   char readbuf[MAXLINE];
550   int readsize = 0;
551   struct sendbuf write_std;
552   write_std.size = 0;
553   write_std.pos = 0;
554
555   struct sendbuf write_pout;
556   write_pout.size = 0;
557   write_pout.pos = 0;
558
559   int ret = 0;
560   int maxfd = 0;
561
562   fd_set rfds;
563   fd_set wfds;
564   struct timeval tv;
565   int retval;
566
567
568
569   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
570   struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
571
572   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout);
573   file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
574
575   //send mac first
576
577   struct Wlan_Helper_Control_Message macmsg;
578
579   //Send random mac address
580   macmsg.mac.mac[0] = 0x13;
581   macmsg.mac.mac[1] = 0x22;
582   macmsg.mac.mac[2] = 0x33;
583   macmsg.mac.mac[3] = 0x44;
584   macmsg.mac.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 255);
585   macmsg.mac.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 255);
586   macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message));
587   macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
588
589   memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
590   write_std.size = sizeof(struct Wlan_Helper_Control_Message);
591
592   /*
593   //wait
594   tv.tv_sec = 2;
595   tv.tv_usec = 0;
596   retval = select(0, NULL, NULL, NULL, &tv);
597
598
599   tv.tv_sec = 3;
600   tv.tv_usec = 0;
601   // if there is something to write
602   FD_ZERO(&wfds);
603   FD_SET(STDOUT_FILENO, &wfds);
604
605   retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv);
606
607   if (FD_ISSET(STDOUT_FILENO, &wfds))
608     {
609       ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size
610           - write_std.pos);
611
612       if (0 > ret)
613         {
614           closeprog = 1;
615           fprintf(stderr, "Write ERROR to STDOUT");
616           exit(1);
617         }
618       else
619         {
620           write_std.pos += ret;
621           // check if finished
622           if (write_std.pos == write_std.size)
623             {
624               write_std.pos = 0;
625               write_std.size = 0;
626             }
627         }
628     }
629
630   memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
631   write_std.size = sizeof(struct Wlan_Helper_Control_Message);
632   */
633
634   //wait
635   tv.tv_sec = 2;
636   tv.tv_usec = 0;
637   retval = select(0, NULL, NULL, NULL, &tv);
638
639   while (0 == closeprog)
640     {
641
642       maxfd = 0;
643
644       //set timeout
645       tv.tv_sec = 5;
646       tv.tv_usec = 0;
647
648       FD_ZERO(&rfds);
649       // if output queue is empty
650       if (0 == write_pout.size)
651         {
652           FD_SET(STDIN_FILENO, &rfds);
653
654         }
655       if (0 == write_std.size)
656         {
657           FD_SET(fdpin, &rfds);
658           maxfd = fdpin;
659         }
660       FD_ZERO(&wfds);
661       // if there is something to write
662       if (0 < write_std.size){
663         FD_SET(STDOUT_FILENO, &wfds);
664         maxfd = MAX(maxfd, STDOUT_FILENO);
665       }
666
667       if (0 < write_pout.size){
668         FD_SET(fdpout, &wfds);
669         maxfd = MAX(maxfd, fdpout);
670       }
671
672
673       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
674
675       if (-1 == retval && EINTR == errno)
676         {
677           continue;
678         }
679       if (0 > retval)
680         {
681           fprintf(stderr, "select failed: %s\n", strerror(errno));
682           exit(1);
683         }
684
685       if (FD_ISSET(STDOUT_FILENO, &wfds))
686         {
687           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
688               write_std.size - write_std.pos);
689
690           if (0 > ret)
691             {
692               closeprog = 1;
693               fprintf(stderr, "Write ERROR to STDOUT");
694               exit(1);
695             }
696           else
697             {
698               write_std.pos += ret;
699               // check if finished
700               if (write_std.pos == write_std.size)
701                 {
702                   write_std.pos = 0;
703                   write_std.size = 0;
704                 }
705             }
706         }
707
708       if (FD_ISSET(fdpout, &wfds))
709         {
710           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
711               - write_pout.pos);
712
713           if (0 > ret)
714             {
715               closeprog = 1;
716               fprintf(stderr, "Write ERROR to fdpout");
717               exit(1);
718             }
719           else
720             {
721               write_pout.pos += ret;
722               // check if finished
723               if (write_pout.pos == write_pout.size)
724                 {
725                   write_pout.pos = 0;
726                   write_pout.size = 0;
727                 }
728             }
729         }
730
731       if (FD_ISSET(STDIN_FILENO, &rfds))
732         {
733           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
734
735           if (0 > readsize)
736             {
737               closeprog = 1;
738               fprintf(stderr, "Read ERROR to STDIN_FILENO");
739               exit(1);
740             }
741           else
742             {
743               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
744                   GNUNET_NO, GNUNET_NO);
745
746             }
747         }
748
749       if (FD_ISSET(fdpin, &rfds))
750         {
751           readsize = read(fdpin, readbuf, sizeof(readbuf));
752
753           if (0 > readsize)
754             {
755               closeprog = 1;
756               fprintf(stderr, "Read ERROR to fdpin");
757               exit(1);
758             }
759           else
760             {
761               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
762                   GNUNET_NO, GNUNET_NO);
763
764             }
765         }
766
767     }
768
769   //clean up
770   fclose(fpout);
771   fclose(fpin);
772
773   if (1 == first)
774     {
775       unlink(FIFO_FILE1);
776       unlink(FIFO_FILE2);
777     }
778
779   return (0);
780 }
781
782
783 int
784 main(int argc, char *argv[])
785 {
786   if (3 != argc)
787     {
788       fprintf(
789           stderr,
790           "This program must be started with the interface and the operating mode as argument.\n");
791       return 1;
792     }
793
794   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
795     {
796
797       return testmode(argc, argv);
798     }
799
800 #if 0
801         u8 u8aSendBuffer[500];
802         char szErrbuf[PCAP_ERRBUF_SIZE];
803         int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
804         int nOrdinal = 0, r, nDelay = 100000;
805         int nRateIndex = 0, retval, bytes;
806         pcap_t *ppcap = NULL;
807         struct bpf_program bpfprogram;
808         char * szProgram = "", fBrokenSocket = 0;
809         u16 u16HeaderLen;
810         char szHostname[PATH_MAX];
811
812         if (gethostname(szHostname, sizeof (szHostname) - 1)) {
813                 perror("unable to get hostname");
814         }
815         szHostname[sizeof (szHostname) - 1] = '\0';
816
817
818         printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com>  GPL2\n");
819
820         while (1) {
821                 int nOptionIndex;
822                 static const struct option optiona[] = {
823                         { "delay", required_argument, NULL, 'd' },
824                         { "fcs", no_argument, &flagMarkWithFCS, 1 },
825                         { "help", no_argument, &flagHelp, 1 },
826                         { "verbose", no_argument, &flagVerbose, 1},
827                         { 0, 0, 0, 0 }
828                 };
829                 int c = getopt_long(argc, argv, "d:hf",
830                         optiona, &nOptionIndex);
831
832                 if (c == -1)
833                         break;
834                 switch (c) {
835                 case 0: // long option
836                         break;
837
838                 case 'h': // help
839                         usage();
840
841                 case 'd': // delay
842                         nDelay = atoi(optarg);
843                         break;
844
845                 case 'f': // mark as FCS attached
846                         flagMarkWithFCS = 1;
847                         break;
848
849                 case 'v': //Verbose / readable output to cout
850                         flagVerbose = 1;
851                         break;
852
853                 default:
854                         printf("unknown switch %c\n", c);
855                         usage();
856                         break;
857                 }
858         }
859
860         if (optind >= argc)
861                 usage();
862
863
864                 // open the interface in pcap
865
866         szErrbuf[0] = '\0';
867         ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
868         if (ppcap == NULL) {
869                 printf("Unable to open interface %s in pcap: %s\n",
870                     argv[optind], szErrbuf);
871                 return (1);
872         }
873
874         //get mac from interface
875
876         /*int sock, j, k;
877         char mac[32];
878
879         sock=socket(PF_INET, SOCK_STREAM, 0);
880         if (-1==sock) {
881                 perror("can not open socket\n");
882                 return 1;
883         }
884
885         if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
886                 perror("ioctl(SIOCGIFHWADDR) ");
887                 return 1;
888         }
889         for (j=0, k=0; j<6; j++) {
890                 k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
891                         (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
892         }
893         mac[sizeof(mac)-1]='\0';
894         */
895
896         //get header type
897         nLinkEncap = pcap_datalink(ppcap);
898         nCaptureHeaderLength = 0;home/mwachs/gnb/bin/
899
900         switch (nLinkEncap) {
901
902                 case DLT_PRISM_HEADER:
903                         printf("DLT_PRISM_HEADER Encap\n");
904                         nCaptureHeaderLength = 0x40;
905                         n80211HeaderLength = 0x20; // ieee80211 comes after this
906                         szProgram = "radio[0x4a:4]==0x13223344";
907                         break;
908
909                 case DLT_IEEE802_11_RADIO:
910                         printf("DLT_IEEE802_11_RADIO Encap\n");
911                         nCaptureHeaderLength = 0x40;
912                         n80211HeaderLength = 0x18; // ieee80211 comes after this
913                         szProgram = "ether[0x0a:4]==0x13223344";
914                         break;
915
916                 default:
917                         printf("!!! unknown encapsulation on %s !\n", argv[1]);
918                         return (1);
919
920         }
921
922         if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
923                 puts(szProgram);
924                 puts(pcap_geterr(ppcap));
925                 return (1);
926         } else {
927                 if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
928                         puts(szProgram);
929                         puts(pcap_geterr(ppcap));
930                 } else {
931                         printf("RX Filter applied\n");
932                 }
933                 pcap_freecode(&bpfprogram);
934         }
935
936         pcap_setnonblock(ppcap, 1, szErrbuf);
937
938         printf("   (delay between packets %dus)\n", nDelay);
939
940         memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
941
942         while (!fBrokenSocket) {
943                 u8 * pu8 = u8aSendBuffer;
944                 struct pcap_pkthdr * ppcapPacketHeader = NULL;
945                 struct ieee80211_radiotap_iterator rti;
946                 PENUMBRA_RADIOTAP_DATA prd;
947                 //init of the values
948                 prd.m_nRate = 255;
949                 prd.m_nChannel = 255;
950                 prd.m_nAntenna = 255;
951                 prd.m_nRadiotapFlags = 255;
952                 u8 * pu8Payload = u8aSendBuffer;
953                 int n, nRate;
954
955                 // receive
956
957                 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
958                     (const u_char**)&pu8Payload);
959
960                 if (retval < 0) {
961                         fBrokenSocket = 1;
962                         continue;
963                 }
964
965                 if (retval != 1)
966                         goto do_tx;
967
968                 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
969
970                 printf("rtap: ");
971                 Dump(pu8Payload, u16HeaderLen);
972
973                 if (ppcapPacketHeader->len <
974                     (u16HeaderLen + n80211HeaderLength))
975                         continue;
976
977                 bytes = ppcapPacketHeader->len -
978                         (u16HeaderLen + n80211HeaderLength);
979                 if (bytes < 0)
980                         continue;
981
982                 if (ieee80211_radiotap_iterator_init(&rti,
983                     (struct ieee80211_radiotap_header *)pu8Payload,
984                     bytes) < 0)
985                         continue;
986
987                 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
988
989                         switch (rti.this_arg_index) {
990                         case IEEE80211_RADIOTAP_RATE:
991                                 prd.m_nRate = (*rti.this_arg);
992                                 break;
993
994                         case IEEE80211_RADIOTAP_CHANNEL:
995                                 prd.m_nChannel =
996                                     le16_to_cpu(*((u16 *)rti.this_arg));
997                                 prd.m_nChannelFlags =
998                                     le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
999                                 break;
1000
1001                         case IEEE80211_RADIOTAP_ANTENNA:
1002                                 prd.m_nAntenna = (*rti.this_arg) + 1;
1003                                 break;
1004
1005                         case IEEE80211_RADIOTAP_FLAGS:
1006                                 prd.m_nRadiotapFlags = *rti.this_arg;
1007                                 break;
1008
1009                         }
1010                 }
1011
1012                 pu8Payload += u16HeaderLen + n80211HeaderLength;
1013
1014                 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1015                         bytes -= 4;
1016
1017                 printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1018                     "Ant: %d, Flags: 0x%X\n",
1019                     prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1020                     prd.m_nChannel / 1000,
1021                     prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
1022                     prd.m_nAntenna,
1023                     prd.m_nRadiotapFlags);
1024
1025                 Dump(pu8Payload, bytes);
1026
1027         do_tx:
1028
1029                 // transmit
1030
1031                 memcpy(u8aSendBuffer, u8aRadiotapHeader,
1032                         sizeof (u8aRadiotapHeader));
1033                 if (flagMarkWithFCS)
1034                         pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1035                 nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1036                 if (nRateIndex >= sizeof (u8aRatesToUse))
1037                         nRateIndex = 0;
1038                 pu8 += sizeof (u8aRadiotapHeader);
1039
1040                 memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
1041                 pu8 += sizeof (u8aIeeeHeader);
1042
1043                 pu8 += sprintf((char *)u8aSendBuffer,
1044                     "Packetspammer %02d"
1045                     "broadcast packet"
1046                     "#%05d -- :-D --%s ----",
1047                     nRate/2, nOrdinal++, szHostname);
1048                 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1049                 if (r != (pu8-u8aSendBuffer)) {
1050                         perror("Trouble injecting packet");
1051                         return (1);
1052                 }
1053                 if (nDelay)
1054                         usleep(nDelay);
1055         }
1056
1057
1058 #endif
1059         return (0);
1060 }
1061