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