Some fixes
[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 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/stat.h>
37 #include <netpacket/packet.h>
38 #include <linux/if_ether.h>
39 #include <linux/if.h>
40 #include <linux/wireless.h>
41 #include <netinet/in.h>
42 #include <linux/if_tun.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <stdarg.h>
47 #include <unistd.h>
48 #include <fcntl.h>
49 #include <errno.h>
50 #include <dirent.h>
51 //#include <sys/utsname.h>
52 #include <sys/param.h>
53
54 /*
55  //#include <resolv.h>
56  #include <string.h>
57  #include <utime.h>
58  //#include <unistd.h>
59  #include <getopt.h>
60  */
61 //#include "platform.h"
62 #include "gnunet_constants.h"
63 #include "gnunet_os_lib.h"
64 #include "gnunet_transport_plugin.h"
65 #include "transport.h"
66 #include "gnunet_util_lib.h"
67 #include "plugin_transport_wlan.h"
68 #include "gnunet_common.h"
69 #include "gnunet-transport-wlan-helper.h"
70 #include "gnunet_crypto_lib.h"
71
72 #include <pcap.h>
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <sys/stat.h>
76
77 #include "wlan/radiotap-parser.h"
78 /* radiotap-parser defines types like u8 that
79  * ieee80211_radiotap.h needs
80  *
81  * we use our local copy of ieee80211_radiotap.h
82  *
83  * - since we can't support extensions we don't understand
84  * - since linux does not include it in userspace headers
85  */
86 #include "wlan/ieee80211_radiotap.h"
87 #include "wlan/crctable_osdep.h"
88 #include "wlan/loopback_helper.h"
89 #include "wlan/ieee80211.h"
90
91 #define ARPHRD_IEEE80211        801
92 #define ARPHRD_IEEE80211_PRISM  802
93 #define ARPHRD_IEEE80211_FULL   803
94
95 int first;
96 int closeprog;
97
98 #include "wlan/helper_common.h"
99 #include "wlan/loopback_helper.h"
100
101 #define DEBUG 1
102
103 typedef enum
104 {
105   DT_NULL = 0,
106   DT_WLANNG,
107   DT_HOSTAP,
108   DT_MADWIFI,
109   DT_MADWIFING,
110   DT_BCM43XX,
111   DT_ORINOCO,
112   DT_ZD1211RW,
113   DT_ACX,
114   DT_MAC80211_RT,
115   DT_AT76USB,
116   DT_IPW2200
117
118 } DRIVER_TYPE;
119
120 static const char * szaDriverTypes[] =
121   { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP",
122       [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG",
123       [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco",
124       [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX",
125       [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb",
126       [DT_IPW2200] = "ipw2200" };
127
128 struct Hardware_Infos
129 {
130
131   struct sendbuf *write_pout;
132   int fd_in, arptype_in;
133   int fd_out, arptype_out;
134   int fd_main;
135   int fd_rtc;
136
137   DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */
138
139   FILE *f_cap_in;
140
141   struct pcap_file_header pfh_in;
142
143   int sysfs_inject;
144   int channel;
145   int freq;
146   int rate;
147   int tx_power;
148   char *wlanctlng; /* XXX never set */
149   char *iwpriv;
150   char *iwconfig;
151   char *ifconfig;
152   char *iface;
153   char *main_if;
154   unsigned char pl_mac[6];
155   int inject_wlanng;
156 };
157
158 //#include "radiotap.h"
159
160 // mac of this node
161 char mac[] =
162   { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 };
163
164 /* wifi bitrate to use in 500kHz units */
165
166 static const u8 u8aRatesToUse[] =
167   {
168
169   54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5
170       2 * 2, 1 * 2 };
171
172 #define OFFSET_FLAGS 0x10
173 #define OFFSET_RATE 0x11
174
175 // this is where we store a summary of the
176 // information from the radiotap header
177
178 typedef struct
179 {
180   int m_nChannel;
181   int m_nChannelFlags;
182   int m_nRate;
183   int m_nAntenna;
184   int m_nRadiotapFlags;
185 }__attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
186
187 static void
188 sigfunc_hw(int sig)
189 {
190   closeprog = 1;
191 }
192
193 void
194 Dump(u8 * pu8, int nLength)
195 {
196   char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
197   unsigned char baaLast[2][16];
198   uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
199
200   buf = szBuf;
201   szChar[0] = '\0';
202
203   for (n = 0; n < nLength; n++)
204     {
205       baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n];
206       if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
207         szChar[n & 0xf] = '.';
208       else
209         szChar[n & 0xf] = pu8[n];
210       szChar[(n & 0xf) + 1] = '\0';
211       nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]);
212       if ((n & 15) != 15)
213         continue;
214       if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst))
215         {
216           nSameCount++;
217         }
218       else
219         {
220           if (nSameCount)
221             buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
222           buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar);
223           nSameCount = 0;
224           printf("%s", szBuf);
225           buf = szBuf;
226         }
227       nPos = 0;
228       nStart = n + 1;
229       nLine++;
230       fFirst = 0;
231       sz[0] = '\0';
232       szChar[0] = '\0';
233     }
234   if (nSameCount)
235     buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
236
237   buf += sprintf(buf, "%04x: %s", nStart, sz);
238   if (n & 0xf)
239     {
240       *buf++ = ' ';
241       while (n & 0xf)
242         {
243           buf += sprintf(buf, "   ");
244           n++;
245         }
246     }
247   buf += sprintf(buf, "%s\n", szChar);
248   printf("%s", szBuf);
249 }
250
251 void
252 usage()
253 {
254   printf("Usage: interface-name optins\n"
255     "options: 0 = with hardware\n"
256     "1 = first loopback file\n"
257     "2 = second loopback file\n"
258     "\n");
259   exit(1);
260 }
261
262 unsigned long
263 calc_crc_osdep(unsigned char * buf, int len)
264 {
265   unsigned long crc = 0xFFFFFFFF;
266
267   for (; len > 0; len--, buf++)
268     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
269
270   return (~crc);
271 }
272
273 /* CRC checksum verification routine */
274
275 int
276 check_crc_buf_osdep(unsigned char *buf, int len)
277 {
278   unsigned long crc;
279
280   if (len < 0)
281     return 0;
282
283   crc = calc_crc_osdep(buf, len);
284   buf += len;
285   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc
286       >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
287 }
288
289 /* Search a file recursively */
290 static char *
291 searchInside(const char * dir, const char * filename)
292 {
293   char * ret;
294   char * curfile;
295   struct stat sb;
296   int len, lentot;
297   DIR *dp;
298   struct dirent *ep;
299
300   dp = opendir(dir);
301   if (dp == NULL)
302     {
303       return NULL;
304     }
305
306   len = strlen(filename);
307   lentot = strlen(dir) + 256 + 2;
308   curfile = (char *) calloc(1, lentot);
309
310   while ((ep = readdir(dp)) != NULL)
311     {
312
313       memset(curfile, 0, lentot);
314       sprintf(curfile, "%s/%s", dir, ep->d_name);
315
316       //Checking if it's the good file
317       if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename))
318         {
319           (void) closedir(dp);
320           return curfile;
321         }
322       lstat(curfile, &sb);
323
324       //If it's a directory and not a link, try to go inside to search
325       if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
326         {
327           //Check if the directory isn't "." or ".."
328           if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name))
329             {
330               //Recursive call
331               ret = searchInside(curfile, filename);
332               if (ret != NULL)
333                 {
334                   (void) closedir(dp);
335                   free(curfile);
336                   return ret;
337                 }
338             }
339         }
340     }
341   (void) closedir(dp);
342   free(curfile);
343   return NULL;
344 }
345
346 /* Search a wireless tool and return its path */
347 static char *
348 wiToolsPath(const char * tool)
349 {
350   char * path;
351   int i, nbelems;
352   static const char * paths[] =
353     { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin",
354         "/usr/local/bin", "/tmp" };
355
356   nbelems = sizeof(paths) / sizeof(char *);
357
358   for (i = 0; i < nbelems; i++)
359     {
360       path = searchInside(paths[i], tool);
361       if (path != NULL)
362         return path;
363     }
364
365   return NULL;
366 }
367
368 static int
369 linux_get_channel(struct Hardware_Infos *dev)
370 {
371   struct iwreq wrq;
372   int fd, frequency;
373   int chan = 0;
374
375   memset(&wrq, 0, sizeof(struct iwreq));
376
377   if (dev->main_if)
378     strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ );
379   else
380     strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
381
382   fd = dev->fd_in;
383   if (dev->drivertype == DT_IPW2200)
384     fd = dev->fd_main;
385
386   if (ioctl(fd, SIOCGIWFREQ, &wrq) < 0)
387     return (-1);
388
389   frequency = wrq.u.freq.m;
390   if (frequency > 100000000)
391     frequency /= 100000;
392   else if (frequency > 1000000)
393     frequency /= 1000;
394
395   if (frequency > 1000)
396     chan = getChannelFromFrequency(frequency);
397   else
398     chan = frequency;
399
400   return chan;
401 }
402
403 static int
404 linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count,
405     struct Radiotap_rx * ri)
406 {
407   unsigned char tmpbuf[4096];
408
409   int caplen, n, got_signal, got_noise, got_channel, fcs_removed;
410
411   caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0;
412
413   if ((unsigned) count > sizeof(tmpbuf))
414     return (-1);
415   caplen = read(dev->fd_in, tmpbuf, count);
416   if (0 > caplen)
417     {
418       if (errno == EAGAIN)
419         return (0);
420
421       perror("read failed");
422       return (-1);
423     }
424
425   memset(buf, 0, sizeof(buf));
426
427   /* XXX */
428   if (ri)
429     memset(ri, 0, sizeof(*ri));
430
431   if (dev->arptype_in == ARPHRD_IEEE80211_PRISM)
432     {
433       /* skip the prism header */
434       if (tmpbuf[7] == 0x40)
435         {
436           /* prism54 uses a different format */
437           if (ri)
438             {
439               ri->ri_power = tmpbuf[0x33];
440               ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
441               ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
442
443               got_signal = 1;
444               got_noise = 1;
445             }
446
447           n = 0x40;
448         }
449       else
450         {
451           if (ri)
452             {
453               ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48);
454               ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
455               ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
456               ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
457               ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
458
459               got_channel = 1;
460               got_signal = 1;
461               got_noise = 1;
462             }
463
464           n = *(int *) (tmpbuf + 4);
465         }
466
467       if (n < 8 || n >= caplen)
468         return (0);
469     }
470
471   if (dev->arptype_in == ARPHRD_IEEE80211_FULL)
472     {
473       struct ieee80211_radiotap_iterator iterator;
474       struct ieee80211_radiotap_header *rthdr;
475
476       rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
477
478       if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0)
479         return (0);
480
481       /* go through the radiotap arguments we have been given
482        * by the driver
483        */
484
485       while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0))
486         {
487
488           switch (iterator.this_arg_index)
489             {
490
491           case IEEE80211_RADIOTAP_TSFT:
492             ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg));
493             break;
494
495           case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
496             if (!got_signal)
497               {
498                 if (*iterator.this_arg < 127)
499                   ri->ri_power = *iterator.this_arg;
500                 else
501                   ri->ri_power = *iterator.this_arg - 255;
502
503                 got_signal = 1;
504               }
505             break;
506
507           case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
508             if (!got_signal)
509               {
510                 if (*iterator.this_arg < 127)
511                   ri->ri_power = *iterator.this_arg;
512                 else
513                   ri->ri_power = *iterator.this_arg - 255;
514
515                 got_signal = 1;
516               }
517             break;
518
519           case IEEE80211_RADIOTAP_DBM_ANTNOISE:
520             if (!got_noise)
521               {
522                 if (*iterator.this_arg < 127)
523                   ri->ri_noise = *iterator.this_arg;
524                 else
525                   ri->ri_noise = *iterator.this_arg - 255;
526
527                 got_noise = 1;
528               }
529             break;
530
531           case IEEE80211_RADIOTAP_DB_ANTNOISE:
532             if (!got_noise)
533               {
534                 if (*iterator.this_arg < 127)
535                   ri->ri_noise = *iterator.this_arg;
536                 else
537                   ri->ri_noise = *iterator.this_arg - 255;
538
539                 got_noise = 1;
540               }
541             break;
542
543           case IEEE80211_RADIOTAP_ANTENNA:
544             ri->ri_antenna = *iterator.this_arg;
545             break;
546
547           case IEEE80211_RADIOTAP_CHANNEL:
548             ri->ri_channel = *iterator.this_arg;
549             got_channel = 1;
550             break;
551
552           case IEEE80211_RADIOTAP_RATE:
553             ri->ri_rate = (*iterator.this_arg) * 500000;
554             break;
555
556           case IEEE80211_RADIOTAP_FLAGS:
557             /* is the CRC visible at the end?
558              * remove
559              */
560             if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
561               {
562                 fcs_removed = 1;
563                 caplen -= 4;
564               }
565
566             if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
567               return (0);
568
569             break;
570
571             }
572         }
573
574       n = le16_to_cpu(rthdr->it_len);
575
576       if (n <= 0 || n >= caplen)
577         return (0);
578     }
579
580   caplen -= n;
581
582   //detect fcs at the end, even if the flag wasn't set and remove it
583   if (fcs_removed == 0 && check_crc_buf_osdep(tmpbuf + n, caplen - 4) == 1)
584     {
585       caplen -= 4;
586     }
587
588   memcpy(buf, tmpbuf + n, caplen);
589
590   if (ri && !got_channel)
591     ri->ri_channel = linux_get_channel(dev);
592
593   return (caplen);
594 }
595
596 static int
597 linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count)
598 {
599   int ret, usedrtap = 0;
600   unsigned short int *p_rtlen;
601
602   unsigned char * u8aRadiotap = buf;
603
604   /* Pointer to the radiotap header length field for later use. */
605   p_rtlen = (unsigned short int*) (u8aRadiotap + 2);
606   usedrtap = 0;
607   ret = write(dev->fd_out, buf, count);
608
609   if (ret < 0)
610     {
611       if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
612           == ENOMEM)
613         {
614           usleep(10000);
615           return (0);
616         }
617
618       perror("write failed");
619       return (-1);
620     }
621
622   /* radiotap header length is stored little endian on all systems */
623   if (usedrtap)
624     ret -= letoh16(*p_rtlen);
625
626   if (ret < 0)
627     {
628       if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
629           == ENOMEM)
630         {
631           usleep(10000);
632           return (0);
633         }
634
635       perror("write failed");
636       return (-1);
637     }
638
639   return (ret);
640 }
641
642 static int
643 openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype,
644     uint8_t *mac)
645 {
646   struct ifreq ifr;
647   struct iwreq wrq;
648   struct packet_mreq mr;
649   struct sockaddr_ll sll;
650
651   /* find the interface index */
652
653   memset(&ifr, 0, sizeof(ifr));
654   strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
655
656   if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
657     {
658       printf("Interface %s: \n", iface);
659       perror("ioctl(SIOCGIFINDEX) failed");
660       return (1);
661     }
662
663   memset(&sll, 0, sizeof(sll));
664   sll.sll_family = AF_PACKET;
665   sll.sll_ifindex = ifr.ifr_ifindex;
666
667   switch (dev->drivertype)
668     {
669   default:
670     sll.sll_protocol = htons(ETH_P_ALL);
671     break;
672     }
673
674   /* lookup the hardware type */
675
676   if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
677     {
678       printf("Interface %s: \n", iface);
679       perror("ioctl(SIOCGIFHWADDR) failed");
680       return (1);
681     }
682
683   /* lookup iw mode */
684   memset(&wrq, 0, sizeof(struct iwreq));
685   strncpy(wrq.ifr_name, iface, IFNAMSIZ);
686
687   if (ioctl(fd, SIOCGIWMODE, &wrq) < 0)
688     {
689       /* most probably not supported (ie for rtap ipw interface) *
690        * so just assume its correctly set...                     */
691       wrq.u.mode = IW_MODE_MONITOR;
692     }
693
694   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
695       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
696       != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR))
697     {
698       printf("Error: %s not in monitor mode\n", iface);
699       return (1);
700     }
701
702   /* Is interface st to up, broadcast & running ? */
703   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
704     {
705       /* Bring interface up*/
706       ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
707
708       if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
709         {
710           perror("ioctl(SIOCSIFFLAGS) failed");
711           return (1);
712         }
713     }
714   /* bind the raw socket to the interface */
715
716   if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0)
717     {
718       printf("Interface %s: \n", iface);
719       perror("bind(ETH_P_ALL) failed");
720       return (1);
721     }
722
723   /* lookup the hardware type */
724
725   if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
726     {
727       printf("Interface %s: \n", iface);
728       perror("ioctl(SIOCGIFHWADDR) failed");
729       return (1);
730     }
731
732   memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6);
733
734   *arptype = ifr.ifr_hwaddr.sa_family;
735
736   if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
737       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
738       != ARPHRD_IEEE80211_FULL)
739     {
740       if (ifr.ifr_hwaddr.sa_family == 1)
741         fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) ");
742       else
743         fprintf(stderr, "\nUnsupported hardware link type %4d ",
744             ifr.ifr_hwaddr.sa_family);
745
746       fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_"
747         "FULL or ARPHRD_IEEE80211_PRISM instead.  Make\n"
748         "sure RFMON is enabled: run 'airmon-ng start %s"
749         " <#>'\nSysfs injection support was not found "
750         "either.\n\n", iface);
751       return (1);
752     }
753
754   /* enable promiscuous mode */
755
756   memset(&mr, 0, sizeof(mr));
757   mr.mr_ifindex = sll.sll_ifindex;
758   mr.mr_type = PACKET_MR_PROMISC;
759
760   if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
761     {
762       perror("setsockopt(PACKET_MR_PROMISC) failed");
763       return (1);
764     }
765
766   return (0);
767 }
768
769 int
770 wlaninit(struct Hardware_Infos * dev, char *iface)
771 {
772
773   char *iwpriv;
774   char strbuf[512];
775   dev->inject_wlanng = 1;
776   dev->rate = 2; /* default to 1Mbps if nothing is set */
777
778   /* open raw socks */
779   dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
780   if (0 > dev->fd_in)
781     {
782       perror("socket(PF_PACKET) failed at fd_in");
783       if (getuid() != 0)
784         fprintf(stderr, "This program requires root privileges.\n");
785       return (1);
786     }
787
788   dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
789   if (0 > dev->fd_main)
790     {
791       perror("socket(PF_PACKET) failed at fd_main");
792       if (getuid() != 0)
793         fprintf(stderr, "This program requires root privileges.\n");
794       return (1);
795     }
796
797   /* Check iwpriv existence */
798
799   iwpriv = wiToolsPath("iwpriv");
800   dev->iwpriv = iwpriv;
801   dev->iwconfig = wiToolsPath("iwconfig");
802   dev->ifconfig = wiToolsPath("ifconfig");
803
804   if (!iwpriv)
805     {
806       fprintf(stderr, "Can't find wireless tools, exiting.\n");
807       goto close_in;
808     }
809
810   dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
811   if (0 > dev->fd_out)
812     {
813       perror("socket(PF_PACKET) failed at fd_out");
814       goto close_in;
815     }
816
817   /* figure out device type */
818
819   /* mac80211 radiotap injection
820    * detected based on interface called mon...
821    * since mac80211 allows multiple virtual interfaces
822    *
823    * note though that the virtual interfaces are ultimately using a
824    * single physical radio: that means for example they must all
825    * operate on the same channel
826    */
827
828   /* mac80211 stack detection */
829   memset(strbuf, 0, sizeof(strbuf));
830   snprintf(strbuf, sizeof(strbuf) - 1,
831       "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface);
832
833   if (system(strbuf) == 0)
834     dev->drivertype = DT_MAC80211_RT;
835
836   else
837     {
838       // At the moment only mac80211 tested
839       return 1;
840     }
841
842 #ifdef DEBUG
843   fprintf(stderr, "Interface %s -> driver: %s\n", iface,
844       szaDriverTypes[dev->drivertype]);
845 #endif
846
847   if (openraw(dev, iface, dev->fd_out, &dev->arptype_out, dev->pl_mac) != 0)
848     {
849       goto close_out;
850     }
851
852   dev->fd_in = dev->fd_out;
853
854   dev->arptype_in = dev->arptype_out;
855
856   return 0;
857   close_out: close(dev->fd_out);
858   close_in: close(dev->fd_in);
859   return 1;
860 }
861
862 /**
863  * function to test incoming packets mac
864  * @param buf buffer of the packet
865  * @param dev pointer to the Hardware_Infos struct
866  * @return 0 if macs are okay, 1 if macs are wrong
867  */
868
869 static int
870 mac_test(unsigned char * buf, struct Hardware_Infos * dev)
871 {
872   struct ieee80211_frame * u8aIeeeHeader;
873   u8aIeeeHeader = (struct ieee80211_frame *) buf;
874   if (0 == memcmp(u8aIeeeHeader->i_addr3, mac_bssid, 6))
875     {
876       if (0 == memcmp(u8aIeeeHeader->i_addr2, dev->pl_mac, 6))
877         {
878           return 0;
879         }
880
881       if (0 == memcmp(u8aIeeeHeader->i_addr2, bc_all_mac, 6))
882         {
883           return 0;
884         }
885     }
886
887   return 1;
888 }
889
890 /**
891  * function to set the wlan header to make attacks more difficult
892  * @param buf buffer of the packet
893  * @param dev pointer to the Hardware_Infos struct
894  */
895
896 static void
897 mac_set(unsigned char * buf, struct Hardware_Infos * dev)
898 {
899   struct ieee80211_frame * u8aIeeeHeader;
900   u8aIeeeHeader = (struct ieee80211_frame *) buf;
901
902   u8aIeeeHeader->i_fc[0] = 0x80;
903   u8aIeeeHeader->i_fc[1] = 0x00;
904
905   memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6);
906   memcpy(u8aIeeeHeader->i_addr3, mac_bssid, 6);
907
908 }
909
910 static void
911 stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
912 {
913   struct Hardware_Infos * dev = cls;
914   struct sendbuf *write_pout = dev->write_pout;
915   struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1];
916   unsigned char * wlanheader;
917
918   int sendsize;
919
920   unsigned char u8aRadiotap[] =
921     { 0x00, 0x00, // <-- radiotap version
922         0x0c, 0x00, // <- radiotap header length
923         0x04, 0x80, 0x00, 0x00, // <-- bitmap
924         0x00, // <-- rate
925         0x00, // <-- padding for natural alignment
926         0x18, 0x00, // <-- TX flags
927       };
928
929   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
930       - sizeof(struct GNUNET_MessageHeader);
931
932   if ((sendsize) > MAXLINE * 2)
933     {
934       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
935       exit(1);
936     }
937
938   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
939     {
940       fprintf(stderr, "Function stdin_send: wrong packet type\n");
941       exit(1);
942     }
943
944   if (sendsize < sizeof(struct ieee80211_frame) + sizeof(struct WlanHeader)
945       + sizeof(struct FragmentationHeader)
946       + sizeof(struct GNUNET_MessageHeader))
947     {
948       fprintf(stderr, "Function stdin_send: packet too small\n");
949       exit(1);
950     }
951
952   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
953   u8aRadiotap[8] = header->rate;
954
955   switch (dev->drivertype)
956     {
957
958   case DT_MAC80211_RT:
959     memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
960     memcpy(write_pout->buf + sizeof(u8aRadiotap), write_pout->buf
961         + sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader),
962         sendsize);
963
964     wlanheader =  write_pout->buf + sizeof(u8aRadiotap);
965     mac_set(wlanheader, dev);
966
967     sendsize += sizeof(u8aRadiotap);
968
969     break;
970   default:
971     break;
972     }
973
974   write_pout->size = sendsize;
975 }
976
977 int
978 maketest(unsigned char * buf, struct Hardware_Infos * dev)
979 {
980   uint16_t * tmp16;
981   static uint16_t seqenz = 0;
982   static int first = 0;
983
984   const int rate = 11000000;
985   static const char
986       txt[] =
987           "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
988
989   unsigned char u8aRadiotap[] =
990     { 0x00, 0x00, // <-- radiotap version
991         0x00, 0x00, // <- radiotap header length
992         0x04, 0x80, 0x02, 0x00, // <-- bitmap
993         0x00, // <-- rate
994         0x00, // <-- padding for natural alignment
995         0x10, 0x00, // <-- TX flags
996         0x04 //retries
997       };
998
999   /*uint8_t u8aRadiotap[] =
1000    {
1001    0x00, 0x00, // <-- radiotap version
1002    0x19, 0x00, // <- radiotap header length
1003    0x6f, 0x08, 0x00, 0x00, // <-- bitmap
1004    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
1005    0x00, // <-- flags (Offset +0x10)
1006    0x6c, // <-- rate (0ffset +0x11)
1007    0x71, 0x09, 0xc0, 0x00, // <-- channel
1008    0xde, // <-- antsignal
1009    0x00, // <-- antnoise
1010    0x01, // <-- antenna
1011    };*/
1012
1013   u8aRadiotap[8] = (rate / 500000);
1014   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
1015
1016   static struct ieee80211_frame u8aIeeeHeader;
1017
1018   uint8_t u8aIeeeHeader_def[] =
1019     { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
1020         //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
1021         //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
1022         0x00, 0x00, // Duration/ID
1023
1024         //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
1025         0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
1026         0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
1027         0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
1028         //0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
1029         0x10, 0x86, //Sequence Control
1030       };
1031   if (first == 0)
1032     {
1033       memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame));
1034       memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6);
1035       first = 1;
1036     }
1037
1038   tmp16 = (uint16_t*) u8aIeeeHeader.i_dur;
1039   *tmp16
1040       = (uint16_t) htole16((sizeof(txt) + sizeof(struct ieee80211_frame) * 1000000) / rate + 290);
1041   tmp16 = (uint16_t*) u8aIeeeHeader.i_seq;
1042   *tmp16 = (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16(seqenz)
1043       << IEEE80211_SEQ_SEQ_SHIFT);
1044   seqenz++;
1045
1046   memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap));
1047   memcpy(buf + sizeof(u8aRadiotap), &u8aIeeeHeader, sizeof(u8aIeeeHeader));
1048   memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt));
1049   return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt);
1050
1051 }
1052
1053 int
1054 hardwaremode(int argc, char *argv[])
1055 {
1056
1057   struct Hardware_Infos dev;
1058   struct ifreq ifreq;
1059   struct Radiotap_rx * rxinfo;
1060   uint8_t * mac = dev.pl_mac;
1061   int fdpin, fdpout;
1062
1063   signal(SIGINT, &sigfunc_hw);
1064   signal(SIGTERM, &sigfunc_hw);
1065
1066   if (wlaninit(&dev, argv[1]))
1067     {
1068       return 1;
1069     }
1070
1071   printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",
1072       ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3],
1073       (int) mac[4], (int) mac[5]);
1074
1075   //return 0;
1076
1077   unsigned char * datastart;
1078   char readbuf[MAXLINE];
1079   int readsize = 0;
1080   struct sendbuf write_std;
1081   write_std.size = 0;
1082   write_std.pos = 0;
1083
1084   struct sendbuf write_pout;
1085   write_pout.size = 0;
1086   write_pout.pos = 0;
1087
1088   dev.write_pout = &write_pout;
1089
1090   int ret = 0;
1091   int maxfd = 0;
1092
1093   fd_set rfds;
1094   fd_set wfds;
1095   struct timeval tv;
1096   int retval;
1097
1098   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
1099
1100   fdpin = dev.fd_in;
1101   fdpout = dev.fd_out;
1102
1103   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
1104
1105   //send mac first
1106
1107   write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac);
1108
1109   //wait
1110   tv.tv_sec = 2;
1111   tv.tv_usec = 0;
1112   retval = select(0, NULL, NULL, NULL, &tv);
1113
1114   while (0 == closeprog)
1115     {
1116
1117       write_pout.size = maketest(write_pout.buf, &dev);
1118       tv.tv_sec = 2;
1119       tv.tv_usec = 0;
1120       retval = select(0, NULL, NULL, NULL, &tv);
1121
1122       maxfd = 0;
1123
1124       //set timeout
1125       tv.tv_sec = 5;
1126       tv.tv_usec = 0;
1127
1128       FD_ZERO(&rfds);
1129       // if output queue is empty
1130       if (0 == write_pout.size)
1131         {
1132           FD_SET(STDIN_FILENO, &rfds);
1133
1134         }
1135       if (0 == write_std.size)
1136         {
1137           //FD_SET(fdpin, &rfds);
1138           //maxfd = fdpin;
1139         }
1140       FD_ZERO(&wfds);
1141       // if there is something to write
1142       if (0 < write_std.size)
1143         {
1144           FD_SET(STDOUT_FILENO, &wfds);
1145           maxfd = MAX(maxfd, STDOUT_FILENO);
1146         }
1147
1148       if (0 < write_pout.size)
1149         {
1150           FD_SET(fdpout, &wfds);
1151           maxfd = MAX(maxfd, fdpout);
1152         }
1153
1154       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1155
1156       if (-1 == retval && EINTR == errno)
1157         {
1158           continue;
1159         }
1160       if (0 > retval)
1161         {
1162           fprintf(stderr, "select failed: %s\n", strerror(errno));
1163           exit(1);
1164         }
1165
1166       if (FD_ISSET(STDOUT_FILENO, &wfds))
1167         {
1168           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
1169               write_std.size - write_std.pos);
1170
1171           if (0 > ret)
1172             {
1173               closeprog = 1;
1174               fprintf(stderr, "Write ERROR to STDOUT\n");
1175               exit(1);
1176             }
1177           else
1178             {
1179               write_std.pos += ret;
1180               // check if finished
1181               if (write_std.pos == write_std.size)
1182                 {
1183                   write_std.pos = 0;
1184                   write_std.size = 0;
1185                 }
1186             }
1187         }
1188
1189       if (FD_ISSET(fdpout, &wfds))
1190         {
1191
1192           ret = linux_write(&dev, write_pout.buf, write_pout.size);
1193
1194           if (0 > ret)
1195             {
1196               closeprog = 1;
1197               fprintf(stderr, "Write ERROR to fdpout\n");
1198             }
1199           else
1200             {
1201               write_pout.pos += ret;
1202               // check if finished
1203               if (write_pout.pos != write_pout.size && ret != 0)
1204                 {
1205                   closeprog = 1;
1206                   fprintf(stderr,
1207                       "Write ERROR packet not in one piece send: %u, %u\n",
1208                       write_pout.pos, write_pout.size);
1209                 }
1210               else if (write_pout.pos == write_pout.size)
1211                 {
1212                   write_pout.pos = 0;
1213                   write_pout.size = 0;
1214                 }
1215
1216             }
1217         }
1218
1219       if (FD_ISSET(STDIN_FILENO, &rfds))
1220         {
1221           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
1222
1223           if (0 > readsize)
1224             {
1225               closeprog = 1;
1226               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
1227             }
1228           else if (0 < readsize)
1229             {
1230               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
1231                   GNUNET_NO, GNUNET_NO);
1232
1233             }
1234           else
1235             {
1236               //eof
1237               closeprog = 1;
1238             }
1239         }
1240
1241       if (FD_ISSET(fdpin, &rfds))
1242         {
1243           rxinfo = (struct Radiotap_rx *) (write_pout.buf
1244               + sizeof(struct GNUNET_MessageHeader));
1245           datastart = (unsigned char *) readbuf + sizeof(struct Radiotap_rx)
1246               + sizeof(struct GNUNET_MessageHeader);
1247
1248           readsize = linux_read(&dev, datastart, sizeof(readbuf)
1249               - sizeof(struct Radiotap_rx)
1250               - sizeof(struct GNUNET_MessageHeader), rxinfo);
1251
1252           if (0 > readsize)
1253             {
1254               closeprog = 1;
1255               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
1256               closeprog = 1;
1257             }
1258           else if (0 < readsize)
1259             {
1260               if (1 == mac_test(datastart, &dev))
1261                 {
1262                   // mac wrong
1263                   write_pout.pos = 0;
1264                   write_pout.size = 0;
1265                 }
1266             }
1267           else
1268             {
1269               //eof
1270               //closeprog = 1;
1271             }
1272         }
1273
1274     }
1275
1276   return 0;
1277
1278 }
1279
1280 int
1281 main(int argc, char *argv[])
1282 {
1283   if (3 != argc)
1284     {
1285       fprintf(
1286           stderr,
1287           "This program must be started with the interface and the operating mode as argument.\n");
1288       usage();
1289       return 1;
1290     }
1291
1292   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
1293     {
1294
1295       return testmode(argc, argv);
1296     }
1297   else
1298     {
1299       return hardwaremode(argc, argv);
1300     }
1301
1302 #if 0
1303   u8 u8aSendBuffer[500];
1304   char szErrbuf[PCAP_ERRBUF_SIZE];
1305   int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
1306   int nOrdinal = 0, r, nDelay = 100000;
1307   int nRateIndex = 0, retval, bytes;
1308   pcap_t *ppcap = NULL;
1309   struct bpf_program bpfprogram;
1310   char * szProgram = "", fBrokenSocket = 0;
1311   u16 u16HeaderLen;
1312   char szHostname[PATH_MAX];
1313
1314   if (gethostname(szHostname, sizeof (szHostname) - 1))
1315     {
1316       perror("unable to get hostname");
1317     }
1318   szHostname[sizeof (szHostname) - 1] = '\0';
1319
1320   printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com>  GPL2\n");
1321
1322   while (1)
1323     {
1324       int nOptionIndex;
1325       static const struct option optiona[] =
1326         {
1327             { "delay", required_argument, NULL, 'd'},
1328             { "fcs", no_argument, &flagMarkWithFCS, 1},
1329             { "help", no_argument, &flagHelp, 1},
1330             { "verbose", no_argument, &flagVerbose, 1},
1331             { 0, 0, 0, 0}
1332         };
1333       int c = getopt_long(argc, argv, "d:hf",
1334           optiona, &nOptionIndex);
1335
1336       if (c == -1)
1337       break;
1338       switch (c)
1339         {
1340           case 0: // long option
1341           break;
1342
1343           case 'h': // help
1344           usage();
1345
1346           case 'd': // delay
1347           nDelay = atoi(optarg);
1348           break;
1349
1350           case 'f': // mark as FCS attached
1351           flagMarkWithFCS = 1;
1352           break;
1353
1354           case 'v': //Verbose / readable output to cout
1355           flagVerbose = 1;
1356           break;
1357
1358           default:
1359           printf("unknown switch %c\n", c);
1360           usage();
1361           break;
1362         }
1363     }
1364
1365   if (optind >= argc)
1366   usage();
1367
1368   // open the interface in pcap
1369
1370   szErrbuf[0] = '\0';
1371   ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1372   if (ppcap == NULL)
1373     {
1374       printf("Unable to open interface %s in pcap: %s\n",
1375           argv[optind], szErrbuf);
1376       return (1);
1377     }
1378
1379   //get mac from interface
1380
1381   /*int sock, j, k;
1382    char mac[32];
1383
1384    sock=socket(PF_INET, SOCK_STREAM, 0);
1385    if (-1==sock) {
1386    perror("can not open socket\n");
1387    return 1;
1388    }
1389
1390    if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1391    perror("ioctl(SIOCGIFHWADDR) ");
1392    return 1;
1393    }
1394    for (j=0, k=0; j<6; j++) {
1395    k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
1396    (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
1397    }
1398    mac[sizeof(mac)-1]='\0';
1399    */
1400
1401   //get header type
1402   nLinkEncap = pcap_datalink(ppcap);
1403   nCaptureHeaderLength = 0;
1404
1405   switch (nLinkEncap)
1406     {
1407
1408       case DLT_PRISM_HEADER:
1409       printf("DLT_PRISM_HEADER Encap\n");
1410       nCaptureHeaderLength = 0x40;
1411       n80211HeaderLength = 0x20; // ieee80211 comes after this
1412       szProgram = "radio[0x4a:4]==0x13223344";
1413       break;
1414
1415       case DLT_IEEE802_11_RADIO:
1416       printf("DLT_IEEE802_11_RADIO Encap\n");
1417       nCaptureHeaderLength = 0x40;
1418       n80211HeaderLength = 0x18; // ieee80211 comes after this
1419       szProgram = "ether[0x0a:4]==0x13223344";
1420       break;
1421
1422       default:
1423       printf("!!! unknown encapsulation on %s !\n", argv[1]);
1424       return (1);
1425
1426     }
1427
1428   if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1)
1429     {
1430       puts(szProgram);
1431       puts(pcap_geterr(ppcap));
1432       return (1);
1433     }
1434   else
1435     {
1436       if (pcap_setfilter(ppcap, &bpfprogram) == -1)
1437         {
1438           puts(szProgram);
1439           puts(pcap_geterr(ppcap));
1440         }
1441       else
1442         {
1443           printf("RX Filter applied\n");
1444         }
1445       pcap_freecode(&bpfprogram);
1446     }
1447
1448   pcap_setnonblock(ppcap, 1, szErrbuf);
1449
1450   printf("   (delay between packets %dus)\n", nDelay);
1451
1452   memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer));
1453
1454   while (!fBrokenSocket)
1455     {
1456       u8 * pu8 = u8aSendBuffer;
1457       struct pcap_pkthdr * ppcapPacketHeader = NULL;
1458       struct ieee80211_radiotap_iterator rti;
1459       PENUMBRA_RADIOTAP_DATA prd;
1460       //init of the values
1461       prd.m_nRate = 255;
1462       prd.m_nChannel = 255;
1463       prd.m_nAntenna = 255;
1464       prd.m_nRadiotapFlags = 255;
1465       u8 * pu8Payload = u8aSendBuffer;
1466       int n, nRate;
1467
1468       // receive
1469
1470       retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1471           (const u_char**) &pu8Payload);
1472
1473       if (retval < 0)
1474         {
1475           fBrokenSocket = 1;
1476           continue;
1477         }
1478
1479       if (retval != 1)
1480       goto do_tx;
1481
1482       u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1483
1484       printf("rtap: ");
1485       Dump(pu8Payload, u16HeaderLen);
1486
1487       if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength))
1488       continue;
1489
1490       bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength);
1491       if (bytes < 0)
1492       continue;
1493
1494       if (ieee80211_radiotap_iterator_init(&rti,
1495               (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0)
1496       continue;
1497
1498       while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0)
1499         {
1500
1501           switch (rti.this_arg_index)
1502             {
1503               case IEEE80211_RADIOTAP_RATE:
1504               prd.m_nRate = (*rti.this_arg);
1505               break;
1506
1507               case IEEE80211_RADIOTAP_CHANNEL:
1508               prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg));
1509               prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1510               break;
1511
1512               case IEEE80211_RADIOTAP_ANTENNA:
1513               prd.m_nAntenna = (*rti.this_arg) + 1;
1514               break;
1515
1516               case IEEE80211_RADIOTAP_FLAGS:
1517               prd.m_nRadiotapFlags = *rti.this_arg;
1518               break;
1519
1520             }
1521         }
1522
1523       pu8Payload += u16HeaderLen + n80211HeaderLength;
1524
1525       if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1526       bytes -= 4;
1527
1528       printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1529           "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1530           prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000)
1531               * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags);
1532
1533       Dump(pu8Payload, bytes);
1534
1535       do_tx:
1536
1537       // transmit
1538
1539       memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader));
1540       if (flagMarkWithFCS)
1541       pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1542       nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1543       if (nRateIndex >= sizeof(u8aRatesToUse))
1544       nRateIndex = 0;
1545       pu8 += sizeof(u8aRadiotapHeader);
1546
1547       memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader));
1548       pu8 += sizeof(u8aIeeeHeader);
1549
1550       pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d"
1551           "broadcast packet"
1552           "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname);
1553       r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1554       if (r != (pu8 - u8aSendBuffer))
1555         {
1556           perror("Trouble injecting packet");
1557           return (1);
1558         }
1559       if (nDelay)
1560       usleep(nDelay);
1561     }
1562
1563 #endif
1564   return (0);
1565 }
1566