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