close helper at eof
[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   uint16_t sendsize;
463
464   sendsize = ntohs(hdr->size);
465
466   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
467     {
468       fprintf (stderr, 
469                "Function file_in_send: wrong packet type\n");
470       exit(1);
471     }
472   if((sendsize + write_std->size) > MAXLINE * 2){
473     fprintf(stderr, "Function file_in_send: Packet too big for buffer\n");
474     exit(1);
475   }
476
477   memcpy(write_std->buf + write_std->size, hdr, sendsize);
478   write_std->size += sendsize;
479 }
480
481 int
482 testmode(int argc, char *argv[])
483 {
484   struct stat st;
485   int erg;
486
487   FILE *fpin;
488   FILE *fpout;
489
490   int fdpin;
491   int fdpout;
492
493   //make the fifos if needed
494   if (0 != stat(FIFO_FILE1, &st))
495     {
496       if (0 == stat(FIFO_FILE2, &st))
497         {
498         fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not\n");
499           exit(1);
500         }
501
502       umask(0);
503       erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0);
504       erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
505
506     }
507   else
508     {
509
510       if (0 != stat(FIFO_FILE2, &st))
511         {
512         fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n");
513           exit(1);
514         }
515
516     }
517
518   if (strstr(argv[2], "1"))
519     {
520       //fprintf(stderr, "First\n");
521       first = 1;
522       fpin = fopen(FIFO_FILE1, "r");
523       if (NULL == fpin)
524         {
525         fprintf(stderr, "fopen of read FIFO_FILE1\n");
526           exit(1);
527         }
528       if (NULL == (fpout = fopen(FIFO_FILE2, "w")))
529         {
530         fprintf(stderr, "fopen of write FIFO_FILE2\n");
531           exit(1);
532         }
533
534     }
535   else
536     {
537       first = 0;
538       //fprintf(stderr, "Second\n");
539       if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
540         {
541         fprintf(stderr, "fopen of write FIFO_FILE1\n");
542           exit(1);
543         }
544       if (NULL == (fpin = fopen(FIFO_FILE2, "r")))
545         {
546         fprintf(stderr, "fopen of read FIFO_FILE2\n");
547           exit(1);
548         }
549
550     }
551
552   fdpin = fileno(fpin);
553   if (fdpin >= FD_SETSIZE)
554     {
555       fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin,
556           (unsigned int) FD_SETSIZE);
557       close(fdpin);
558       return -1;
559     }
560
561   fdpout = fileno(fpout);
562   if (fdpout >= FD_SETSIZE)
563     {
564       fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout,
565           (unsigned int) FD_SETSIZE);
566       close(fdpout);
567       return -1;
568
569     }
570
571   signal(SIGINT, &sigfunc);
572   signal(SIGTERM, &sigfunc);
573
574   char readbuf[MAXLINE];
575   int readsize = 0;
576   struct sendbuf write_std;
577   write_std.size = 0;
578   write_std.pos = 0;
579
580   struct sendbuf write_pout;
581   write_pout.size = 0;
582   write_pout.pos = 0;
583
584   int ret = 0;
585   int maxfd = 0;
586
587   fd_set rfds;
588   fd_set wfds;
589   struct timeval tv;
590   int retval;
591
592
593
594   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
595   struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
596
597   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout);
598   file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
599
600   //send mac first
601
602   struct Wlan_Helper_Control_Message macmsg;
603
604   //Send random mac address
605   macmsg.mac.mac[0] = 0x13;
606   macmsg.mac.mac[1] = 0x22;
607   macmsg.mac.mac[2] = 0x33;
608   macmsg.mac.mac[3] = 0x44;
609   macmsg.mac.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 256);
610   macmsg.mac.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 256);
611   macmsg.hdr.size = htons(sizeof(struct Wlan_Helper_Control_Message));
612   macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
613
614   memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
615   write_std.size = sizeof(struct Wlan_Helper_Control_Message);
616
617   /*
618   //wait
619   tv.tv_sec = 2;
620   tv.tv_usec = 0;
621   retval = select(0, NULL, NULL, NULL, &tv);
622
623
624   tv.tv_sec = 3;
625   tv.tv_usec = 0;
626   // if there is something to write
627   FD_ZERO(&wfds);
628   FD_SET(STDOUT_FILENO, &wfds);
629
630   retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv);
631
632   if (FD_ISSET(STDOUT_FILENO, &wfds))
633     {
634       ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size
635           - write_std.pos);
636
637       if (0 > ret)
638         {
639           closeprog = 1;
640           fprintf(stderr, "Write ERROR to STDOUT");
641           exit(1);
642         }
643       else
644         {
645           write_std.pos += ret;
646           // check if finished
647           if (write_std.pos == write_std.size)
648             {
649               write_std.pos = 0;
650               write_std.size = 0;
651             }
652         }
653     }
654
655   memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
656   write_std.size = sizeof(struct Wlan_Helper_Control_Message);
657   */
658
659   //wait
660   tv.tv_sec = 2;
661   tv.tv_usec = 0;
662   retval = select(0, NULL, NULL, NULL, &tv);
663
664   while (0 == closeprog)
665     {
666
667       maxfd = 0;
668
669       //set timeout
670       tv.tv_sec = 5;
671       tv.tv_usec = 0;
672
673       FD_ZERO(&rfds);
674       // if output queue is empty
675       if (0 == write_pout.size)
676         {
677           FD_SET(STDIN_FILENO, &rfds);
678
679         }
680       if (0 == write_std.size)
681         {
682           FD_SET(fdpin, &rfds);
683           maxfd = fdpin;
684         }
685       FD_ZERO(&wfds);
686       // if there is something to write
687       if (0 < write_std.size){
688         FD_SET(STDOUT_FILENO, &wfds);
689         maxfd = MAX(maxfd, STDOUT_FILENO);
690       }
691
692       if (0 < write_pout.size){
693         FD_SET(fdpout, &wfds);
694         maxfd = MAX(maxfd, fdpout);
695       }
696
697
698       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
699
700       if (-1 == retval && EINTR == errno)
701         {
702           continue;
703         }
704       if (0 > retval)
705         {
706           fprintf(stderr, "select failed: %s\n", strerror(errno));
707           exit(1);
708         }
709
710       if (FD_ISSET(STDOUT_FILENO, &wfds))
711         {
712           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
713               write_std.size - write_std.pos);
714
715           if (0 > ret)
716             {
717               closeprog = 1;
718               fprintf(stderr, "Write ERROR to STDOUT\n");
719               exit(1);
720             }
721           else
722             {
723               write_std.pos += ret;
724               // check if finished
725               if (write_std.pos == write_std.size)
726                 {
727                   write_std.pos = 0;
728                   write_std.size = 0;
729                 }
730             }
731         }
732
733       if (FD_ISSET(fdpout, &wfds))
734         {
735           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
736               - write_pout.pos);
737
738           if (0 > ret)
739             {
740               closeprog = 1;
741               fprintf(stderr, "Write ERROR to fdpout\n");
742             }
743           else
744             {
745               write_pout.pos += ret;
746               // check if finished
747               if (write_pout.pos == write_pout.size)
748                 {
749                   write_pout.pos = 0;
750                   write_pout.size = 0;
751                 }
752             }
753         }
754
755       if (FD_ISSET(STDIN_FILENO, &rfds))
756         {
757           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
758
759           if (0 > readsize)
760             {
761               closeprog = 1;
762               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
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           else
771             {
772               //eof
773               closeprog = 1;
774             }
775         }
776
777       if (FD_ISSET(fdpin, &rfds))
778         {
779           readsize = read(fdpin, readbuf, sizeof(readbuf));
780
781           if (0 > readsize)
782             {
783               closeprog = 1;
784               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
785               closeprog = 1;
786             }
787           else if (0 < readsize)
788             {
789               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
790                   GNUNET_NO, GNUNET_NO);
791
792             }
793           else
794             {
795               //eof
796               closeprog = 1;
797             }
798         }
799
800     }
801
802   //clean up
803   fclose(fpout);
804   fclose(fpin);
805
806   if (1 == first)
807     {
808       unlink(FIFO_FILE1);
809       unlink(FIFO_FILE2);
810     }
811
812   return (0);
813 }
814
815
816 int
817 main(int argc, char *argv[])
818 {
819   if (3 != argc)
820     {
821       fprintf(
822           stderr,
823           "This program must be started with the interface and the operating mode as argument.\n");
824       return 1;
825     }
826
827   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
828     {
829
830       return testmode(argc, argv);
831     }
832
833 #if 0
834         u8 u8aSendBuffer[500];
835         char szErrbuf[PCAP_ERRBUF_SIZE];
836         int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
837         int nOrdinal = 0, r, nDelay = 100000;
838         int nRateIndex = 0, retval, bytes;
839         pcap_t *ppcap = NULL;
840         struct bpf_program bpfprogram;
841         char * szProgram = "", fBrokenSocket = 0;
842         u16 u16HeaderLen;
843         char szHostname[PATH_MAX];
844
845         if (gethostname(szHostname, sizeof (szHostname) - 1)) {
846                 perror("unable to get hostname");
847         }
848         szHostname[sizeof (szHostname) - 1] = '\0';
849
850
851         printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com>  GPL2\n");
852
853         while (1) {
854                 int nOptionIndex;
855                 static const struct option optiona[] = {
856                         { "delay", required_argument, NULL, 'd' },
857                         { "fcs", no_argument, &flagMarkWithFCS, 1 },
858                         { "help", no_argument, &flagHelp, 1 },
859                         { "verbose", no_argument, &flagVerbose, 1},
860                         { 0, 0, 0, 0 }
861                 };
862                 int c = getopt_long(argc, argv, "d:hf",
863                         optiona, &nOptionIndex);
864
865                 if (c == -1)
866                         break;
867                 switch (c) {
868                 case 0: // long option
869                         break;
870
871                 case 'h': // help
872                         usage();
873
874                 case 'd': // delay
875                         nDelay = atoi(optarg);
876                         break;
877
878                 case 'f': // mark as FCS attached
879                         flagMarkWithFCS = 1;
880                         break;
881
882                 case 'v': //Verbose / readable output to cout
883                         flagVerbose = 1;
884                         break;
885
886                 default:
887                         printf("unknown switch %c\n", c);
888                         usage();
889                         break;
890                 }
891         }
892
893         if (optind >= argc)
894                 usage();
895
896
897                 // open the interface in pcap
898
899         szErrbuf[0] = '\0';
900         ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
901         if (ppcap == NULL) {
902                 printf("Unable to open interface %s in pcap: %s\n",
903                     argv[optind], szErrbuf);
904                 return (1);
905         }
906
907         //get mac from interface
908
909         /*int sock, j, k;
910         char mac[32];
911
912         sock=socket(PF_INET, SOCK_STREAM, 0);
913         if (-1==sock) {
914                 perror("can not open socket\n");
915                 return 1;
916         }
917
918         if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
919                 perror("ioctl(SIOCGIFHWADDR) ");
920                 return 1;
921         }
922         for (j=0, k=0; j<6; j++) {
923                 k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
924                         (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
925         }
926         mac[sizeof(mac)-1]='\0';
927         */
928
929         //get header type
930         nLinkEncap = pcap_datalink(ppcap);
931         nCaptureHeaderLength = 0;home/mwachs/gnb/bin/
932
933         switch (nLinkEncap) {
934
935                 case DLT_PRISM_HEADER:
936                         printf("DLT_PRISM_HEADER Encap\n");
937                         nCaptureHeaderLength = 0x40;
938                         n80211HeaderLength = 0x20; // ieee80211 comes after this
939                         szProgram = "radio[0x4a:4]==0x13223344";
940                         break;
941
942                 case DLT_IEEE802_11_RADIO:
943                         printf("DLT_IEEE802_11_RADIO Encap\n");
944                         nCaptureHeaderLength = 0x40;
945                         n80211HeaderLength = 0x18; // ieee80211 comes after this
946                         szProgram = "ether[0x0a:4]==0x13223344";
947                         break;
948
949                 default:
950                         printf("!!! unknown encapsulation on %s !\n", argv[1]);
951                         return (1);
952
953         }
954
955         if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
956                 puts(szProgram);
957                 puts(pcap_geterr(ppcap));
958                 return (1);
959         } else {
960                 if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
961                         puts(szProgram);
962                         puts(pcap_geterr(ppcap));
963                 } else {
964                         printf("RX Filter applied\n");
965                 }
966                 pcap_freecode(&bpfprogram);
967         }
968
969         pcap_setnonblock(ppcap, 1, szErrbuf);
970
971         printf("   (delay between packets %dus)\n", nDelay);
972
973         memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
974
975         while (!fBrokenSocket) {
976                 u8 * pu8 = u8aSendBuffer;
977                 struct pcap_pkthdr * ppcapPacketHeader = NULL;
978                 struct ieee80211_radiotap_iterator rti;
979                 PENUMBRA_RADIOTAP_DATA prd;
980                 //init of the values
981                 prd.m_nRate = 255;
982                 prd.m_nChannel = 255;
983                 prd.m_nAntenna = 255;
984                 prd.m_nRadiotapFlags = 255;
985                 u8 * pu8Payload = u8aSendBuffer;
986                 int n, nRate;
987
988                 // receive
989
990                 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
991                     (const u_char**)&pu8Payload);
992
993                 if (retval < 0) {
994                         fBrokenSocket = 1;
995                         continue;
996                 }
997
998                 if (retval != 1)
999                         goto do_tx;
1000
1001                 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1002
1003                 printf("rtap: ");
1004                 Dump(pu8Payload, u16HeaderLen);
1005
1006                 if (ppcapPacketHeader->len <
1007                     (u16HeaderLen + n80211HeaderLength))
1008                         continue;
1009
1010                 bytes = ppcapPacketHeader->len -
1011                         (u16HeaderLen + n80211HeaderLength);
1012                 if (bytes < 0)
1013                         continue;
1014
1015                 if (ieee80211_radiotap_iterator_init(&rti,
1016                     (struct ieee80211_radiotap_header *)pu8Payload,
1017                     bytes) < 0)
1018                         continue;
1019
1020                 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
1021
1022                         switch (rti.this_arg_index) {
1023                         case IEEE80211_RADIOTAP_RATE:
1024                                 prd.m_nRate = (*rti.this_arg);
1025                                 break;
1026
1027                         case IEEE80211_RADIOTAP_CHANNEL:
1028                                 prd.m_nChannel =
1029                                     le16_to_cpu(*((u16 *)rti.this_arg));
1030                                 prd.m_nChannelFlags =
1031                                     le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1032                                 break;
1033
1034                         case IEEE80211_RADIOTAP_ANTENNA:
1035                                 prd.m_nAntenna = (*rti.this_arg) + 1;
1036                                 break;
1037
1038                         case IEEE80211_RADIOTAP_FLAGS:
1039                                 prd.m_nRadiotapFlags = *rti.this_arg;
1040                                 break;
1041
1042                         }
1043                 }
1044
1045                 pu8Payload += u16HeaderLen + n80211HeaderLength;
1046
1047                 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1048                         bytes -= 4;
1049
1050                 printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1051                     "Ant: %d, Flags: 0x%X\n",
1052                     prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1053                     prd.m_nChannel / 1000,
1054                     prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
1055                     prd.m_nAntenna,
1056                     prd.m_nRadiotapFlags);
1057
1058                 Dump(pu8Payload, bytes);
1059
1060         do_tx:
1061
1062                 // transmit
1063
1064                 memcpy(u8aSendBuffer, u8aRadiotapHeader,
1065                         sizeof (u8aRadiotapHeader));
1066                 if (flagMarkWithFCS)
1067                         pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1068                 nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1069                 if (nRateIndex >= sizeof (u8aRatesToUse))
1070                         nRateIndex = 0;
1071                 pu8 += sizeof (u8aRadiotapHeader);
1072
1073                 memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
1074                 pu8 += sizeof (u8aIeeeHeader);
1075
1076                 pu8 += sprintf((char *)u8aSendBuffer,
1077                     "Packetspammer %02d"
1078                     "broadcast packet"
1079                     "#%05d -- :-D --%s ----",
1080                     nRate/2, nOrdinal++, szHostname);
1081                 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1082                 if (r != (pu8-u8aSendBuffer)) {
1083                         perror("Trouble injecting packet");
1084                         return (1);
1085                 }
1086                 if (nDelay)
1087                         usleep(nDelay);
1088         }
1089
1090
1091 #endif
1092         return (0);
1093 }
1094