Cleanup and working version with hardware
[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 <unistd.h>
35 #include <sys/wait.h>
36 #include <sys/time.h>
37 #include <sys/stat.h>
38 #include <netpacket/packet.h>
39 #include <linux/if_ether.h>
40 #include <linux/if.h>
41 #include <linux/wireless.h>
42 #include <netinet/in.h>
43 #include <linux/if_tun.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <stdarg.h>
48 #include <unistd.h>
49 #include <fcntl.h>
50 #include <errno.h>
51 #include <dirent.h>
52 //#include <sys/utsname.h>
53 #include <sys/param.h>
54
55 /*
56  //#include <resolv.h>
57  #include <string.h>
58  #include <utime.h>
59  //#include <unistd.h>
60  #include <getopt.h>
61  */
62 //#include "platform.h"
63 #include "gnunet_constants.h"
64 #include "gnunet_os_lib.h"
65 #include "gnunet_transport_plugin.h"
66 #include "transport.h"
67 #include "gnunet_util_lib.h"
68 #include "plugin_transport_wlan.h"
69 #include "gnunet_common.h"
70 #include "gnunet-transport-wlan-helper.h"
71 #include "gnunet_crypto_lib.h"
72
73 #include <pcap.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <sys/stat.h>
77
78 #include "wlan/radiotap-parser.h"
79 /* radiotap-parser defines types like u8 that
80  * ieee80211_radiotap.h needs
81  *
82  * we use our local copy of ieee80211_radiotap.h
83  *
84  * - since we can't support extensions we don't understand
85  * - since linux does not include it in userspace headers
86  */
87 #include "wlan/ieee80211_radiotap.h"
88 #include "wlan/crctable_osdep.h"
89 #include "wlan/loopback_helper.h"
90 #include "wlan/ieee80211.h"
91
92 #define ARPHRD_IEEE80211        801
93 #define ARPHRD_IEEE80211_PRISM  802
94 #define ARPHRD_IEEE80211_FULL   803
95
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;
134   //int arptype_out;
135   //int fd_main;
136   //int fd_rtc;
137
138   DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */
139
140   //FILE *f_cap_in;
141
142   //struct pcap_file_header pfh_in;
143
144   //int sysfs_inject;
145   //int channel;
146   //int freq;
147   //int rate;
148   //int tx_power;
149   //char *wlanctlng; /* XXX never set */
150   //char *iwpriv;
151   //char *iwconfig;
152   //char *ifconfig;
153   char *iface;
154   //char *main_if;
155   unsigned char pl_mac[6];
156 //int inject_wlanng;
157 };
158
159 //#include "radiotap.h"
160
161 // mac of this node
162 /*char mac[] =
163  { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 };
164  */
165 /* wifi bitrate to use in 500kHz units */
166
167 /*
168  static const u8 u8aRatesToUse[] =
169  {
170
171  54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5
172  2 * 2, 1 * 2 };
173
174  #define        OFFSET_FLAGS 0x10
175  #define        OFFSET_RATE 0x11
176  */
177 // this is where we store a summary of the
178 // information from the radiotap header
179
180 /*
181  typedef struct
182  {
183  int m_nChannel;
184  int m_nChannelFlags;
185  int m_nRate;
186  int m_nAntenna;
187  int m_nRadiotapFlags;
188  }__attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
189  */
190 static void
191 sigfunc_hw(int sig)
192 {
193   closeprog = 1;
194 }
195
196 /*
197  void
198  Dump(u8 * pu8, int nLength)
199  {
200  char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
201  unsigned char baaLast[2][16];
202  uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
203
204  buf = szBuf;
205  szChar[0] = '\0';
206
207  for (n = 0; n < nLength; n++)
208  {
209  baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n];
210  if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
211  szChar[n & 0xf] = '.';
212  else
213  szChar[n & 0xf] = pu8[n];
214  szChar[(n & 0xf) + 1] = '\0';
215  nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]);
216  if ((n & 15) != 15)
217  continue;
218  if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst))
219  {
220  nSameCount++;
221  }
222  else
223  {
224  if (nSameCount)
225  buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
226  buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar);
227  nSameCount = 0;
228  printf("%s", szBuf);
229  buf = szBuf;
230  }
231  nPos = 0;
232  nStart = n + 1;
233  nLine++;
234  fFirst = 0;
235  sz[0] = '\0';
236  szChar[0] = '\0';
237  }
238  if (nSameCount)
239  buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
240
241  buf += sprintf(buf, "%04x: %s", nStart, sz);
242  if (n & 0xf)
243  {
244  *buf++ = ' ';
245  while (n & 0xf)
246  {
247  buf += sprintf(buf, "   ");
248  n++;
249  }
250  }
251  buf += sprintf(buf, "%s\n", szChar);
252  printf("%s", szBuf);
253  }
254  */
255 static void
256 usage()
257 {
258   printf("Usage: interface-name options\n"
259     "options: 0 = with hardware\n"
260     "1 = first loopback file\n"
261     "2 = second loopback file\n"
262     "\n");
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 * 4];
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;
608   //int usedrtap;
609   //unsigned short int *p_rtlen;
610
611   //unsigned char * u8aRadiotap = buf;
612
613   /* Pointer to the radiotap header length field for later use. */
614   //p_rtlen = (unsigned short int*) (u8aRadiotap + 2);
615   //usedrtap = 0;
616   ret = write(dev->fd_out, buf, count);
617
618   if (ret < 0)
619     {
620       if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
621           == ENOMEM)
622         {
623           usleep(10000);
624           return (0);
625         }
626
627       perror("write failed");
628       return (-1);
629     }
630
631   /* radiotap header length is stored little endian on all systems */
632   /*if (usedrtap)
633    ret -= letoh16(*p_rtlen);
634
635    if (ret < 0)
636    {
637    if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
638    == ENOMEM)
639    {
640    usleep(10000);
641    return (0);
642    }
643
644    perror("write failed");
645    return (-1);
646    }*/
647
648   return (ret);
649 }
650
651 static int
652 openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype,
653     uint8_t *mac)
654 {
655   struct ifreq ifr;
656   struct iwreq wrq;
657   struct packet_mreq mr;
658   struct sockaddr_ll sll;
659
660   /* find the interface index */
661
662   memset(&ifr, 0, sizeof(ifr));
663   strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
664
665   if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
666     {
667       printf("Interface %s: \n", iface);
668       perror("ioctl(SIOCGIFINDEX) failed");
669       return (1);
670     }
671
672   memset(&sll, 0, sizeof(sll));
673   sll.sll_family = AF_PACKET;
674   sll.sll_ifindex = ifr.ifr_ifindex;
675
676   sll.sll_protocol = htons(ETH_P_ALL);
677
678   /* lookup the hardware type */
679
680   if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
681     {
682       printf("Interface %s: \n", iface);
683       perror("ioctl(SIOCGIFHWADDR) failed");
684       return (1);
685     }
686
687   /* lookup iw mode */
688   memset(&wrq, 0, sizeof(struct iwreq));
689   strncpy(wrq.ifr_name, iface, IFNAMSIZ);
690
691   if (ioctl(fd, SIOCGIWMODE, &wrq) < 0)
692     {
693       /* most probably not supported (ie for rtap ipw interface) *
694        * so just assume its correctly set...                     */
695       wrq.u.mode = IW_MODE_MONITOR;
696     }
697
698   if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
699       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
700       != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR))
701     {
702       printf("Error: %s not in monitor mode\n", iface);
703       return (1);
704     }
705
706   /* Is interface st to up, broadcast & running ? */
707   if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
708     {
709       /* Bring interface up*/
710       ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
711
712       if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
713         {
714           perror("ioctl(SIOCSIFFLAGS) failed");
715           return (1);
716         }
717     }
718   /* bind the raw socket to the interface */
719
720   if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0)
721     {
722       printf("Interface %s: \n", iface);
723       perror("bind(ETH_P_ALL) failed");
724       return (1);
725     }
726
727   /* lookup the hardware type */
728
729   if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
730     {
731       printf("Interface %s: \n", iface);
732       perror("ioctl(SIOCGIFHWADDR) failed");
733       return (1);
734     }
735
736   memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6);
737
738   *arptype = ifr.ifr_hwaddr.sa_family;
739
740   if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family
741       != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family
742       != ARPHRD_IEEE80211_FULL)
743     {
744       if (ifr.ifr_hwaddr.sa_family == 1)
745         fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) ");
746       else
747         fprintf(stderr, "\nUnsupported hardware link type %4d ",
748             ifr.ifr_hwaddr.sa_family);
749
750       fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_"
751         "FULL or ARPHRD_IEEE80211_PRISM instead.  Make\n"
752         "sure RFMON is enabled: run 'airmon-ng start %s"
753         " <#>'\nSysfs injection support was not found "
754         "either.\n\n", iface);
755       return (1);
756     }
757
758   /* enable promiscuous mode */
759
760   memset(&mr, 0, sizeof(mr));
761   mr.mr_ifindex = sll.sll_ifindex;
762   mr.mr_type = PACKET_MR_PROMISC;
763
764   if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
765     {
766       perror("setsockopt(PACKET_MR_PROMISC) failed");
767       return (1);
768     }
769
770   return (0);
771 }
772
773 int
774 wlaninit(struct Hardware_Infos * dev, char *iface)
775 {
776
777   //char *iwpriv;
778   char strbuf[512];
779   //dev->inject_wlanng = 1;
780   //dev->rate = 2; /* default to 1Mbps if nothing is set */
781
782   /* open raw socks */
783   /*
784    dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
785    if (0 > dev->fd_in)
786    {
787    perror("socket(PF_PACKET) failed at fd_in");
788    if (getuid() != 0)
789    fprintf(stderr, "This program requires root privileges.\n");
790    return (1);
791    }
792    */
793   /*
794    dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
795    if (0 > dev->fd_main)
796    {
797    perror("socket(PF_PACKET) failed at fd_main");
798    if (getuid() != 0)
799    fprintf(stderr, "This program requires root privileges.\n");
800    return (1);
801    }
802    */
803   /* Check iwpriv existence */
804   /*
805    iwpriv = wiToolsPath("iwpriv");
806    dev->iwpriv = iwpriv;
807    dev->iwconfig = wiToolsPath("iwconfig");
808    dev->ifconfig = wiToolsPath("ifconfig");
809
810    if (!iwpriv)
811    {
812    fprintf(stderr, "Can't find wireless tools, exiting.\n");
813    goto close_in;
814    }
815    */
816   dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
817   if (0 > dev->fd_out)
818     {
819       perror("socket(PF_PACKET) failed at fd_out");
820       goto close_in;
821     }
822
823   /* figure out device type */
824
825   /* mac80211 radiotap injection
826    * detected based on interface called mon...
827    * since mac80211 allows multiple virtual interfaces
828    *
829    * note though that the virtual interfaces are ultimately using a
830    * single physical radio: that means for example they must all
831    * operate on the same channel
832    */
833
834   /* mac80211 stack detection */
835   memset(strbuf, 0, sizeof(strbuf));
836   snprintf(strbuf, sizeof(strbuf) - 1,
837       "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface);
838
839   if (system(strbuf) == 0)
840     dev->drivertype = DT_MAC80211_RT;
841
842   else
843     {
844       // At the moment only mac80211 tested
845       fprintf(stderr, "only mac80211 stack supported, exiting.\n");
846       return 1;
847     }
848
849 #ifdef DEBUG
850   fprintf(stderr, "Interface %s -> driver: %s\n", iface,
851       szaDriverTypes[dev->drivertype]);
852 #endif
853
854   if (openraw(dev, iface, dev->fd_out, &dev->arptype_in, dev->pl_mac) != 0)
855     {
856       goto close_out;
857     }
858
859   dev->fd_in = dev->fd_out;
860   dev->iface = GNUNET_malloc(sizeof(char) *6);
861   strncpy(dev->iface, iface, sizeof(char) * 6);
862
863   //dev->arptype_out = dev->arptype_in;
864
865   return 0;
866   close_out: close(dev->fd_out);
867   close_in: close(dev->fd_in);
868   return 1;
869 }
870
871 /**
872  * function to test incoming packets mac
873  * @param buf buffer of the packet
874  * @param dev pointer to the Hardware_Infos struct
875  * @return 0 if macs are okay, 1 if macs are wrong
876  */
877
878 static int
879 mac_test(unsigned char * buf, struct Hardware_Infos * dev)
880 {
881   struct ieee80211_frame * u8aIeeeHeader;
882   u8aIeeeHeader = (struct ieee80211_frame *) buf;
883   if (0 == memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, 6))
884     {
885       if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, 6))
886         {
887           return 0;
888         }
889
890       if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, 6))
891         {
892           return 0;
893         }
894     }
895
896   return 1;
897 }
898
899 /**
900  * function to set the wlan header to make attacks more difficult
901  * @param buf buffer of the packet
902  * @param dev pointer to the Hardware_Infos struct
903  */
904
905 static void
906 mac_set(unsigned char * buf, struct Hardware_Infos * dev)
907 {
908   struct ieee80211_frame * u8aIeeeHeader;
909   u8aIeeeHeader = (struct ieee80211_frame *) buf;
910
911   u8aIeeeHeader->i_fc[0] = 0x08;
912   u8aIeeeHeader->i_fc[1] = 0x00;
913
914   memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6);
915   memcpy(u8aIeeeHeader->i_addr3, &mac_bssid, 6);
916
917 }
918
919 static void
920 stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
921 {
922   struct Hardware_Infos * dev = cls;
923   struct sendbuf *write_pout = dev->write_pout;
924   struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1];
925   unsigned char * wlanheader;
926
927   int sendsize;
928
929   unsigned char u8aRadiotap[] =
930     { 0x00, 0x00, // <-- radiotap version
931         0x0c, 0x00, // <- radiotap header length
932         0x04, 0x80, 0x00, 0x00, // <-- bitmap
933         0x00, // <-- rate
934         0x00, // <-- padding for natural alignment
935         0x18, 0x00, // <-- TX flags
936       };
937
938   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
939       - sizeof(struct GNUNET_MessageHeader);
940
941   if ((sendsize) > MAXLINE * 2)
942     {
943       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
944       exit(1);
945     }
946
947   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
948     {
949       fprintf(stderr, "Function stdin_send: wrong packet type\n");
950       exit(1);
951     }
952
953   if (sendsize < sizeof(struct ieee80211_frame)
954       + sizeof(struct GNUNET_MessageHeader))
955     {
956       fprintf(stderr, "Function stdin_send: packet too small\n");
957       exit(1);
958     }
959
960   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
961   u8aRadiotap[8] = header->rate;
962
963   switch (dev->drivertype)
964     {
965
966   case DT_MAC80211_RT:
967     memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
968     memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize);
969
970     wlanheader = write_pout->buf + sizeof(u8aRadiotap);
971     mac_set(wlanheader, dev);
972
973     sendsize += sizeof(u8aRadiotap);
974
975     break;
976   default:
977     break;
978     }
979
980   write_pout->size = sendsize;
981 }
982
983 static int
984 maketest(unsigned char * buf, struct Hardware_Infos * dev)
985 {
986   uint16_t * tmp16;
987   static uint16_t seqenz = 0;
988   static int first = 0;
989
990   const int rate = 11000000;
991   static const char
992       txt[] =
993           "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
994
995   unsigned char u8aRadiotap[] =
996     { 0x00, 0x00, // <-- radiotap version
997         0x00, 0x00, // <- radiotap header length
998         0x04, 0x80, 0x02, 0x00, // <-- bitmap
999         0x00, // <-- rate
1000         0x00, // <-- padding for natural alignment
1001         0x10, 0x00, // <-- TX flags
1002         0x04 //retries
1003       };
1004
1005   /*uint8_t u8aRadiotap[] =
1006    {
1007    0x00, 0x00, // <-- radiotap version
1008    0x19, 0x00, // <- radiotap header length
1009    0x6f, 0x08, 0x00, 0x00, // <-- bitmap
1010    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
1011    0x00, // <-- flags (Offset +0x10)
1012    0x6c, // <-- rate (0ffset +0x11)
1013    0x71, 0x09, 0xc0, 0x00, // <-- channel
1014    0xde, // <-- antsignal
1015    0x00, // <-- antnoise
1016    0x01, // <-- antenna
1017    };*/
1018
1019   u8aRadiotap[8] = (rate / 500000);
1020   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
1021
1022   static struct ieee80211_frame u8aIeeeHeader;
1023
1024   uint8_t u8aIeeeHeader_def[] =
1025     { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
1026         //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
1027         //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
1028         0x00, 0x00, // Duration/ID
1029
1030         //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
1031         0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
1032         0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
1033         //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
1034         0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
1035         0x10, 0x86, //Sequence Control
1036       };
1037   if (first == 0)
1038     {
1039       memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame));
1040       memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6);
1041       first = 1;
1042     }
1043
1044   tmp16 = (uint16_t*) u8aIeeeHeader.i_dur;
1045   *tmp16
1046       = (uint16_t) htole16((sizeof(txt) + sizeof(struct ieee80211_frame) * 1000000) / rate + 290);
1047   tmp16 = (uint16_t*) u8aIeeeHeader.i_seq;
1048   *tmp16 = (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16(seqenz)
1049       << IEEE80211_SEQ_SEQ_SHIFT);
1050   seqenz++;
1051
1052   memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap));
1053   memcpy(buf + sizeof(u8aRadiotap), &u8aIeeeHeader, sizeof(u8aIeeeHeader));
1054   memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt));
1055   return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt);
1056
1057 }
1058
1059 int
1060 hardwaremode(int argc, char *argv[])
1061 {
1062
1063   uid_t uid;
1064   struct Hardware_Infos dev;
1065   //struct ifreq ifreq;
1066   struct Radiotap_rx * rxinfo;
1067   uint8_t * mac = dev.pl_mac;
1068   int fdpin, fdpout;
1069
1070   struct GNUNET_MessageHeader * header;
1071
1072   signal(SIGINT, &sigfunc_hw);
1073   signal(SIGTERM, &sigfunc_hw);
1074
1075   if (wlaninit(&dev, argv[1]))
1076     {
1077       return 1;
1078     }
1079
1080   uid = getuid();
1081   //if (0 != setresuid(uid, uid, uid))
1082   //{
1083   //  fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1084   /* not critical, continue anyway */
1085   //}
1086
1087   /*printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",
1088    ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3],
1089    (int) mac[4], (int) mac[5]);*/
1090
1091   //return 0;
1092
1093   unsigned char * datastart;
1094   char readbuf[MAXLINE];
1095   int readsize = 0;
1096   struct sendbuf write_std;
1097   write_std.size = 0;
1098   write_std.pos = 0;
1099
1100   struct sendbuf write_pout;
1101   write_pout.size = 0;
1102   write_pout.pos = 0;
1103
1104   dev.write_pout = &write_pout;
1105
1106   int ret = 0;
1107   int maxfd = 0;
1108
1109   fd_set rfds;
1110   fd_set wfds;
1111   struct timeval tv;
1112   int retval;
1113
1114   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
1115
1116   fdpin = dev.fd_in;
1117   fdpout = dev.fd_out;
1118
1119   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
1120
1121   //send mac first
1122
1123   write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac);
1124
1125   //wait
1126   tv.tv_sec = 2;
1127   tv.tv_usec = 0;
1128   retval = select(0, NULL, NULL, NULL, &tv);
1129
1130   while (0 == closeprog)
1131     {
1132
1133       //write_pout.size = maketest(write_pout.buf, &dev);
1134       //tv.tv_sec = 2;
1135       //tv.tv_usec = 0;
1136       //select(0, NULL, NULL, NULL, &tv);
1137
1138       maxfd = 0;
1139
1140       //set timeout
1141       tv.tv_sec = 5;
1142       tv.tv_usec = 0;
1143
1144       FD_ZERO(&rfds);
1145       // if output queue is empty
1146       if (0 == write_pout.size)
1147         {
1148           FD_SET(STDIN_FILENO, &rfds);
1149
1150         }
1151       if (0 == write_std.size)
1152         {
1153           FD_SET(fdpin, &rfds);
1154           maxfd = fdpin;
1155         }
1156       FD_ZERO(&wfds);
1157       // if there is something to write
1158       if (0 < write_std.size)
1159         {
1160           FD_SET(STDOUT_FILENO, &wfds);
1161           maxfd = MAX(maxfd, STDOUT_FILENO);
1162         }
1163
1164       if (0 < write_pout.size)
1165         {
1166           FD_SET(fdpout, &wfds);
1167           maxfd = MAX(maxfd, fdpout);
1168         }
1169
1170       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1171
1172       if (-1 == retval && EINTR == errno)
1173         {
1174           continue;
1175         }
1176       if (0 > retval)
1177         {
1178           fprintf(stderr, "select failed: %s\n", strerror(errno));
1179           exit(1);
1180         }
1181
1182       if (FD_ISSET(STDOUT_FILENO, &wfds))
1183         {
1184           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
1185               write_std.size - write_std.pos);
1186
1187           if (0 > ret)
1188             {
1189               closeprog = 1;
1190               fprintf(stderr, "Write ERROR to STDOUT\n");
1191               goto end;
1192             }
1193           else
1194             {
1195               write_std.pos += ret;
1196               // check if finished
1197               if (write_std.pos == write_std.size)
1198                 {
1199                   write_std.pos = 0;
1200                   write_std.size = 0;
1201                 }
1202             }
1203         }
1204
1205       if (FD_ISSET(fdpout, &wfds))
1206         {
1207
1208           ret = linux_write(&dev, write_pout.buf, write_pout.size);
1209
1210           if (0 > ret)
1211             {
1212               closeprog = 1;
1213               fprintf(stderr, "Write ERROR to fdpout\n");
1214             }
1215           else
1216             {
1217               write_pout.pos += ret;
1218               // check if finished
1219               if (write_pout.pos != write_pout.size && ret != 0)
1220                 {
1221                   closeprog = 1;
1222                   fprintf(stderr,
1223                       "Write ERROR packet not in one piece send: %u, %u\n",
1224                       write_pout.pos, write_pout.size);
1225                 }
1226               else if (write_pout.pos == write_pout.size)
1227                 {
1228                   write_pout.pos = 0;
1229                   write_pout.size = 0;
1230                 }
1231
1232             }
1233         }
1234
1235       if (FD_ISSET(STDIN_FILENO, &rfds))
1236         {
1237           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
1238
1239           if (0 > readsize)
1240             {
1241               closeprog = 1;
1242               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
1243             }
1244           else if (0 < readsize)
1245             {
1246               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
1247                   GNUNET_NO, GNUNET_NO);
1248
1249             }
1250           else
1251             {
1252               //eof
1253               closeprog = 1;
1254             }
1255         }
1256
1257       if (FD_ISSET(fdpin, &rfds))
1258         {
1259           rxinfo = (struct Radiotap_rx *) (write_std.buf
1260               + sizeof(struct GNUNET_MessageHeader));
1261           datastart = (unsigned char *) write_std.buf
1262               + sizeof(struct Radiotap_rx)
1263               + sizeof(struct GNUNET_MessageHeader);
1264
1265           readsize = linux_read(&dev, datastart, sizeof(write_std.buf)
1266               - sizeof(struct Radiotap_rx)
1267               - sizeof(struct GNUNET_MessageHeader), rxinfo);
1268
1269           if (0 > readsize)
1270             {
1271               closeprog = 1;
1272               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
1273               closeprog = 1;
1274             }
1275           else if (0 < readsize)
1276             {
1277               if (1 == mac_test(datastart, &dev))
1278                 {
1279                   // mac wrong
1280                   write_std.pos = 0;
1281                   write_std.size = 0;
1282                 }
1283               else
1284                 {
1285                   header = (struct GNUNET_MessageHeader *) write_std.buf;
1286                   write_std.size = readsize
1287                       + sizeof(struct GNUNET_MessageHeader)
1288                       + sizeof(struct Radiotap_rx);
1289                   header->size = htons(write_std.size);
1290                   header->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1291                   fprintf(stderr, "Got packet with size: %u, size std %u\n",
1292                       readsize, write_std.size);
1293
1294                 }
1295             }
1296           else
1297             {
1298               //eof
1299               //closeprog = 1;
1300             }
1301         }
1302
1303     }
1304
1305   GNUNET_SERVER_mst_destroy(stdin_mst);
1306   return 0;
1307
1308   end: GNUNET_SERVER_mst_destroy(stdin_mst);
1309   return 1;
1310
1311 }
1312
1313 int
1314 main(int argc, char *argv[])
1315 {
1316   int ret = 0;
1317   if (3 != argc)
1318     {
1319       fprintf(
1320           stderr,
1321           "This program must be started with the interface and the operating mode as argument.\n");
1322       usage();
1323       return 1;
1324     }
1325
1326   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
1327     {
1328
1329       ret = testmode(argc, argv);
1330     }
1331   else
1332     {
1333
1334       ret = hardwaremode(argc, argv);
1335     }
1336
1337 #if 0
1338   u8 u8aSendBuffer[500];
1339   char szErrbuf[PCAP_ERRBUF_SIZE];
1340   int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
1341   int nOrdinal = 0, r, nDelay = 100000;
1342   int nRateIndex = 0, retval, bytes;
1343   pcap_t *ppcap = NULL;
1344   struct bpf_program bpfprogram;
1345   char * szProgram = "", fBrokenSocket = 0;
1346   u16 u16HeaderLen;
1347   char szHostname[PATH_MAX];
1348
1349   if (gethostname(szHostname, sizeof (szHostname) - 1))
1350     {
1351       perror("unable to get hostname");
1352     }
1353   szHostname[sizeof (szHostname) - 1] = '\0';
1354
1355   printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com>  GPL2\n");
1356
1357   while (1)
1358     {
1359       int nOptionIndex;
1360       static const struct option optiona[] =
1361         {
1362             { "delay", required_argument, NULL, 'd'},
1363             { "fcs", no_argument, &flagMarkWithFCS, 1},
1364             { "help", no_argument, &flagHelp, 1},
1365             { "verbose", no_argument, &flagVerbose, 1},
1366             { 0, 0, 0, 0}
1367         };
1368       int c = getopt_long(argc, argv, "d:hf",
1369           optiona, &nOptionIndex);
1370
1371       if (c == -1)
1372       break;
1373       switch (c)
1374         {
1375           case 0: // long option
1376           break;
1377
1378           case 'h': // help
1379           usage();
1380
1381           case 'd': // delay
1382           nDelay = atoi(optarg);
1383           break;
1384
1385           case 'f': // mark as FCS attached
1386           flagMarkWithFCS = 1;
1387           break;
1388
1389           case 'v': //Verbose / readable output to cout
1390           flagVerbose = 1;
1391           break;
1392
1393           default:
1394           printf("unknown switch %c\n", c);
1395           usage();
1396           break;
1397         }
1398     }
1399
1400   if (optind >= argc)
1401   usage();
1402
1403   // open the interface in pcap
1404
1405   szErrbuf[0] = '\0';
1406   ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1407   if (ppcap == NULL)
1408     {
1409       printf("Unable to open interface %s in pcap: %s\n",
1410           argv[optind], szErrbuf);
1411       return (1);
1412     }
1413
1414   //get mac from interface
1415
1416   /*int sock, j, k;
1417    char mac[32];
1418
1419    sock=socket(PF_INET, SOCK_STREAM, 0);
1420    if (-1==sock) {
1421    perror("can not open socket\n");
1422    return 1;
1423    }
1424
1425    if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1426    perror("ioctl(SIOCGIFHWADDR) ");
1427    return 1;
1428    }
1429    for (j=0, k=0; j<6; j++) {
1430    k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
1431    (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
1432    }
1433    mac[sizeof(mac)-1]='\0';
1434    */
1435
1436   //get header type
1437   nLinkEncap = pcap_datalink(ppcap);
1438   nCaptureHeaderLength = 0;
1439
1440   switch (nLinkEncap)
1441     {
1442
1443       case DLT_PRISM_HEADER:
1444       printf("DLT_PRISM_HEADER Encap\n");
1445       nCaptureHeaderLength = 0x40;
1446       n80211HeaderLength = 0x20; // ieee80211 comes after this
1447       szProgram = "radio[0x4a:4]==0x13223344";
1448       break;
1449
1450       case DLT_IEEE802_11_RADIO:
1451       printf("DLT_IEEE802_11_RADIO Encap\n");
1452       nCaptureHeaderLength = 0x40;
1453       n80211HeaderLength = 0x18; // ieee80211 comes after this
1454       szProgram = "ether[0x0a:4]==0x13223344";
1455       break;
1456
1457       default:
1458       printf("!!! unknown encapsulation on %s !\n", argv[1]);
1459       return (1);
1460
1461     }
1462
1463   if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1)
1464     {
1465       puts(szProgram);
1466       puts(pcap_geterr(ppcap));
1467       return (1);
1468     }
1469   else
1470     {
1471       if (pcap_setfilter(ppcap, &bpfprogram) == -1)
1472         {
1473           puts(szProgram);
1474           puts(pcap_geterr(ppcap));
1475         }
1476       else
1477         {
1478           printf("RX Filter applied\n");
1479         }
1480       pcap_freecode(&bpfprogram);
1481     }
1482
1483   pcap_setnonblock(ppcap, 1, szErrbuf);
1484
1485   printf("   (delay between packets %dus)\n", nDelay);
1486
1487   memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer));
1488
1489   while (!fBrokenSocket)
1490     {
1491       u8 * pu8 = u8aSendBuffer;
1492       struct pcap_pkthdr * ppcapPacketHeader = NULL;
1493       struct ieee80211_radiotap_iterator rti;
1494       PENUMBRA_RADIOTAP_DATA prd;
1495       //init of the values
1496       prd.m_nRate = 255;
1497       prd.m_nChannel = 255;
1498       prd.m_nAntenna = 255;
1499       prd.m_nRadiotapFlags = 255;
1500       u8 * pu8Payload = u8aSendBuffer;
1501       int n, nRate;
1502
1503       // receive
1504
1505       retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1506           (const u_char**) &pu8Payload);
1507
1508       if (retval < 0)
1509         {
1510           fBrokenSocket = 1;
1511           continue;
1512         }
1513
1514       if (retval != 1)
1515       goto do_tx;
1516
1517       u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1518
1519       printf("rtap: ");
1520       Dump(pu8Payload, u16HeaderLen);
1521
1522       if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength))
1523       continue;
1524
1525       bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength);
1526       if (bytes < 0)
1527       continue;
1528
1529       if (ieee80211_radiotap_iterator_init(&rti,
1530               (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0)
1531       continue;
1532
1533       while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0)
1534         {
1535
1536           switch (rti.this_arg_index)
1537             {
1538               case IEEE80211_RADIOTAP_RATE:
1539               prd.m_nRate = (*rti.this_arg);
1540               break;
1541
1542               case IEEE80211_RADIOTAP_CHANNEL:
1543               prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg));
1544               prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1545               break;
1546
1547               case IEEE80211_RADIOTAP_ANTENNA:
1548               prd.m_nAntenna = (*rti.this_arg) + 1;
1549               break;
1550
1551               case IEEE80211_RADIOTAP_FLAGS:
1552               prd.m_nRadiotapFlags = *rti.this_arg;
1553               break;
1554
1555             }
1556         }
1557
1558       pu8Payload += u16HeaderLen + n80211HeaderLength;
1559
1560       if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1561       bytes -= 4;
1562
1563       printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1564           "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1565           prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000)
1566               * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags);
1567
1568       Dump(pu8Payload, bytes);
1569
1570       do_tx:
1571
1572       // transmit
1573
1574       memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader));
1575       if (flagMarkWithFCS)
1576       pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1577       nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1578       if (nRateIndex >= sizeof(u8aRatesToUse))
1579       nRateIndex = 0;
1580       pu8 += sizeof(u8aRadiotapHeader);
1581
1582       memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader));
1583       pu8 += sizeof(u8aIeeeHeader);
1584
1585       pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d"
1586           "broadcast packet"
1587           "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname);
1588       r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1589       if (r != (pu8 - u8aSendBuffer))
1590         {
1591           perror("Trouble injecting packet");
1592           return (1);
1593         }
1594       if (nDelay)
1595       usleep(nDelay);
1596     }
1597
1598 #endif
1599
1600   return ret;
1601   maketest(NULL, NULL);
1602 }
1603