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