9111a6666e31abfabbfda22b89a3e5759bb3d964
[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 void
263 packet_callback(unsigned char *Args, const struct pcap_pkthdr* Pkthdr,
264     unsigned char *Packet)
265 {
266   fprintf(stderr, "+");
267   fflush(stderr);
268 }
269
270 unsigned long
271 calc_crc_osdep(unsigned char * buf, int len)
272 {
273   unsigned long crc = 0xFFFFFFFF;
274
275   for (; len > 0; len--, buf++)
276     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
277
278   return (~crc);
279 }
280
281 /* CRC checksum verification routine */
282
283 int
284 check_crc_buf_osdep(unsigned char *buf, int len)
285 {
286   unsigned long crc;
287
288   if (len < 0)
289     return 0;
290
291   crc = calc_crc_osdep(buf, len);
292   buf += len;
293   return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc
294       >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
295 }
296
297 /* Search a file recursively */
298 static char *
299 searchInside(const char * dir, const char * filename)
300 {
301   char * ret;
302   char * curfile;
303   struct stat sb;
304   int len, lentot;
305   DIR *dp;
306   struct dirent *ep;
307
308   dp = opendir(dir);
309   if (dp == NULL)
310     {
311       return NULL;
312     }
313
314   len = strlen(filename);
315   lentot = strlen(dir) + 256 + 2;
316   curfile = (char *) calloc(1, lentot);
317
318   while ((ep = readdir(dp)) != NULL)
319     {
320
321       memset(curfile, 0, lentot);
322       sprintf(curfile, "%s/%s", dir, ep->d_name);
323
324       //Checking if it's the good file
325       if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename))
326         {
327           (void) closedir(dp);
328           return curfile;
329         }
330       lstat(curfile, &sb);
331
332       //If it's a directory and not a link, try to go inside to search
333       if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
334         {
335           //Check if the directory isn't "." or ".."
336           if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name))
337             {
338               //Recursive call
339               ret = searchInside(curfile, filename);
340               if (ret != NULL)
341                 {
342                   (void) closedir(dp);
343                   free(curfile);
344                   return ret;
345                 }
346             }
347         }
348     }
349   (void) closedir(dp);
350   free(curfile);
351   return NULL;
352 }
353
354 /* Search a wireless tool and return its path */
355 static char *
356 wiToolsPath(const char * tool)
357 {
358   char * path;
359   int i, nbelems;
360   static const char * paths[] =
361     { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin",
362         "/usr/local/bin", "/tmp" };
363
364   nbelems = sizeof(paths) / sizeof(char *);
365
366   for (i = 0; i < nbelems; i++)
367     {
368       path = searchInside(paths[i], tool);
369       if (path != NULL)
370         return path;
371     }
372
373   return NULL;
374 }
375
376 static int
377 linux_get_channel(struct Hardware_Infos *dev)
378 {
379   struct iwreq wrq;
380   int fd, frequency;
381   int chan = 0;
382
383   memset(&wrq, 0, sizeof(struct iwreq));
384
385   if (dev->main_if)
386     strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ );
387   else
388     strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
389
390   fd = dev->fd_in;
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 rx_info * 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   dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
788   if (0 > dev->fd_in)
789     {
790       perror("socket(PF_PACKET) failed at fd_in");
791       if (getuid() != 0)
792         fprintf(stderr, "This program requires root privileges.\n");
793       return (1);
794     }
795
796   dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
797   if (0 > dev->fd_main)
798     {
799       perror("socket(PF_PACKET) failed at fd_main");
800       if (getuid() != 0)
801         fprintf(stderr, "This program requires root privileges.\n");
802       return (1);
803     }
804
805   /* Check iwpriv existence */
806
807   iwpriv = wiToolsPath("iwpriv");
808   dev->iwpriv = iwpriv;
809   dev->iwconfig = wiToolsPath("iwconfig");
810   dev->ifconfig = wiToolsPath("ifconfig");
811
812   if (!iwpriv)
813     {
814       fprintf(stderr, "Can't find wireless tools, exiting.\n");
815       goto close_in;
816     }
817
818   dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
819   if (0 > dev->fd_out)
820     {
821       perror("socket(PF_PACKET) failed at fd_out");
822       goto close_in;
823     }
824
825   /* figure out device type */
826
827   /* mac80211 radiotap injection
828    * detected based on interface called mon...
829    * since mac80211 allows multiple virtual interfaces
830    *
831    * note though that the virtual interfaces are ultimately using a
832    * single physical radio: that means for example they must all
833    * operate on the same channel
834    */
835
836   /* mac80211 stack detection */
837   memset(strbuf, 0, sizeof(strbuf));
838   snprintf(strbuf, sizeof(strbuf) - 1,
839       "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface);
840
841   if (system(strbuf) == 0)
842     dev->drivertype = DT_MAC80211_RT;
843
844   else
845     {
846       // At the moment only mac80211 tested
847       return 1;
848     }
849
850 #ifdef DEBUG
851   fprintf(stderr, "Interface %s -> driver: %s\n", iface,
852       szaDriverTypes[dev->drivertype]);
853 #endif
854
855   if (openraw(dev, iface, dev->fd_out, &dev->arptype_out, dev->pl_mac) != 0)
856     {
857       goto close_out;
858     }
859
860   dev->fd_in = dev->fd_out;
861
862   dev->arptype_in = dev->arptype_out;
863
864   return 0;
865   close_out: close(dev->fd_out);
866   close_in: close(dev->fd_in);
867   return 1;
868 }
869
870 static void
871 stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
872 {
873   struct Hardware_Infos * dev = cls;
874   struct sendbuf *write_pout = dev->write_pout;
875   struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1];
876   int sendsize;
877
878   unsigned char u8aRadiotap[] =
879     { 0x00, 0x00, // <-- radiotap version
880         0x0c, 0x00, // <- radiotap header length
881         0x04, 0x80, 0x00, 0x00, // <-- bitmap
882         0x00, // <-- rate
883         0x00, // <-- padding for natural alignment
884         0x18, 0x00, // <-- TX flags
885       };
886
887   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
888       - sizeof(struct GNUNET_MessageHeader);
889
890   if ((sendsize) > MAXLINE * 2)
891     {
892       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
893       exit(1);
894     }
895
896   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
897     {
898       fprintf(stderr, "Function stdin_send: wrong packet type\n");
899       exit(1);
900     }
901
902   u8aRadiotap[8] = header->rate;
903
904   switch (dev->drivertype)
905     {
906
907   case DT_MAC80211_RT:
908     memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
909     memcpy(write_pout->buf + sizeof(u8aRadiotap), write_pout->buf
910         + sizeof(struct Radiotap_Send) + sizeof(struct GNUNET_MessageHeader),
911         sendsize);
912     sendsize += sizeof(u8aRadiotap);
913
914     //usedrtap = 1;
915     break;
916   default:
917     break;
918     }
919
920   write_pout->size = sendsize;
921 }
922
923 int
924 maketest(unsigned char * buf, struct Hardware_Infos * dev)
925 {
926   uint16_t * tmp16;
927   static uint16_t seqenz = 0;
928   static int first = 0;
929
930   const int rate = 11000000;
931   static const char
932       txt[] =
933           "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
934
935   unsigned char u8aRadiotap[] =
936     { 0x00, 0x00, // <-- radiotap version
937         0x00, 0x00, // <- radiotap header length
938         0x04, 0x80, 0x02, 0x00, // <-- bitmap
939         0x00, // <-- rate
940         0x00, // <-- padding for natural alignment
941         0x10, 0x00, // <-- TX flags
942         0x04 //retries
943       };
944
945   /*uint8_t u8aRadiotap[] =
946    {
947    0x00, 0x00, // <-- radiotap version
948    0x19, 0x00, // <- radiotap header length
949    0x6f, 0x08, 0x00, 0x00, // <-- bitmap
950    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
951    0x00, // <-- flags (Offset +0x10)
952    0x6c, // <-- rate (0ffset +0x11)
953    0x71, 0x09, 0xc0, 0x00, // <-- channel
954    0xde, // <-- antsignal
955    0x00, // <-- antnoise
956    0x01, // <-- antenna
957    };*/
958
959   u8aRadiotap[8] = (rate/500000);
960   u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
961
962   static struct ieee80211_frame u8aIeeeHeader;
963
964   uint8_t u8aIeeeHeader_def[] =
965     { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
966         //      b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
967         //      0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
968         0x00, 0x00, // Duration/ID
969
970         //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
971         0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
972         0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
973         0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
974         //0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
975         0x10, 0x86, //Sequence Control
976       };
977   if (first == 0)
978     {
979       memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame));
980       memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6);
981       first = 1;
982     }
983
984   tmp16 = (uint16_t*) u8aIeeeHeader.i_dur;
985   *tmp16 = (uint16_t) htole16((sizeof(txt) + sizeof(struct ieee80211_frame) * 1000000) / rate + 290);
986   tmp16 = (uint16_t*) u8aIeeeHeader.i_seq;
987   *tmp16 = (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16(seqenz)
988       << IEEE80211_SEQ_SEQ_SHIFT);
989   seqenz++;
990
991   memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap));
992   memcpy(buf + sizeof(u8aRadiotap), &u8aIeeeHeader, sizeof(u8aIeeeHeader));
993   memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt));
994   return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt);
995
996 }
997
998 int
999 hardwaremode(int argc, char *argv[])
1000 {
1001
1002   struct Hardware_Infos dev;
1003   struct ifreq ifreq;
1004   struct rx_info * rxinfo;
1005   uint8_t * mac = dev.pl_mac;
1006   int fdpin, fdpout;
1007
1008   signal(SIGINT, &sigfunc_hw);
1009   signal(SIGTERM, &sigfunc_hw);
1010
1011   if (wlaninit(&dev, argv[1]))
1012     {
1013       return 1;
1014     }
1015
1016   printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",
1017       ifreq.ifr_name, (int) mac[0], (int) mac[1], (int) mac[2], (int) mac[3],
1018       (int) mac[4], (int) mac[5]);
1019
1020   //return 0;
1021
1022   char readbuf[MAXLINE];
1023   int readsize = 0;
1024   struct sendbuf write_std;
1025   write_std.size = 0;
1026   write_std.pos = 0;
1027
1028   struct sendbuf write_pout;
1029   write_pout.size = 0;
1030   write_pout.pos = 0;
1031
1032   dev.write_pout = &write_pout;
1033
1034   int ret = 0;
1035   int maxfd = 0;
1036
1037   fd_set rfds;
1038   fd_set wfds;
1039   struct timeval tv;
1040   int retval;
1041
1042   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
1043
1044   fdpin = dev.fd_in;
1045   fdpout = dev.fd_out;
1046
1047   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
1048
1049   //send mac first
1050
1051   write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac);
1052
1053   //wait
1054   tv.tv_sec = 2;
1055   tv.tv_usec = 0;
1056   retval = select(0, NULL, NULL, NULL, &tv);
1057
1058   while (0 == closeprog)
1059     {
1060
1061       write_pout.size = maketest(write_pout.buf, &dev);
1062       tv.tv_sec = 2;
1063       tv.tv_usec = 0;
1064       retval = select(0, NULL, NULL, NULL, &tv);
1065
1066       maxfd = 0;
1067
1068       //set timeout
1069       tv.tv_sec = 5;
1070       tv.tv_usec = 0;
1071
1072       FD_ZERO(&rfds);
1073       // if output queue is empty
1074       if (0 == write_pout.size)
1075         {
1076           FD_SET(STDIN_FILENO, &rfds);
1077
1078         }
1079       if (0 == write_std.size)
1080         {
1081           //FD_SET(fdpin, &rfds);
1082           //maxfd = fdpin;
1083         }
1084       FD_ZERO(&wfds);
1085       // if there is something to write
1086       if (0 < write_std.size)
1087         {
1088           FD_SET(STDOUT_FILENO, &wfds);
1089           maxfd = MAX(maxfd, STDOUT_FILENO);
1090         }
1091
1092       if (0 < write_pout.size)
1093         {
1094           FD_SET(fdpout, &wfds);
1095           maxfd = MAX(maxfd, fdpout);
1096         }
1097
1098       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1099
1100       if (-1 == retval && EINTR == errno)
1101         {
1102           continue;
1103         }
1104       if (0 > retval)
1105         {
1106           fprintf(stderr, "select failed: %s\n", strerror(errno));
1107           exit(1);
1108         }
1109
1110       if (FD_ISSET(STDOUT_FILENO, &wfds))
1111         {
1112           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
1113               write_std.size - write_std.pos);
1114
1115           if (0 > ret)
1116             {
1117               closeprog = 1;
1118               fprintf(stderr, "Write ERROR to STDOUT\n");
1119               exit(1);
1120             }
1121           else
1122             {
1123               write_std.pos += ret;
1124               // check if finished
1125               if (write_std.pos == write_std.size)
1126                 {
1127                   write_std.pos = 0;
1128                   write_std.size = 0;
1129                 }
1130             }
1131         }
1132
1133       if (FD_ISSET(fdpout, &wfds))
1134         {
1135
1136           ret = linux_write(&dev, write_pout.buf, write_pout.size);
1137           //ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
1138           //    - write_pout.pos);
1139
1140           if (0 > ret)
1141             {
1142               closeprog = 1;
1143               fprintf(stderr, "Write ERROR to fdpout\n");
1144             }
1145           else
1146             {
1147               write_pout.pos += ret;
1148               // check if finished
1149               if (write_pout.pos != write_pout.size && ret != 0)
1150                 {
1151                   closeprog = 1;
1152                   fprintf(stderr,
1153                       "Write ERROR packet not in one piece send: %u, %u\n",
1154                       write_pout.pos, write_pout.size);
1155                 }
1156               else if (write_pout.pos == write_pout.size)
1157                 {
1158                   write_pout.pos = 0;
1159                   write_pout.size = 0;
1160                 }
1161
1162             }
1163         }
1164
1165       if (FD_ISSET(STDIN_FILENO, &rfds))
1166         {
1167           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
1168
1169           if (0 > readsize)
1170             {
1171               closeprog = 1;
1172               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
1173             }
1174           else if (0 < readsize)
1175             {
1176               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
1177                   GNUNET_NO, GNUNET_NO);
1178
1179             }
1180           else
1181             {
1182               //eof
1183               closeprog = 1;
1184             }
1185         }
1186
1187       if (FD_ISSET(fdpin, &rfds))
1188         {
1189           rxinfo = (struct rx_info *) (write_pout.buf
1190               + sizeof(struct GNUNET_MessageHeader));
1191           readsize = linux_read(&dev, (unsigned char *) readbuf
1192               + sizeof(struct rx_info) + sizeof(struct GNUNET_MessageHeader),
1193               sizeof(readbuf) - sizeof(struct rx_info)
1194                   - sizeof(struct GNUNET_MessageHeader), rxinfo);
1195           //readsize = read(fdpin, readbuf, sizeof(readbuf));
1196
1197           if (0 > readsize)
1198             {
1199               closeprog = 1;
1200               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
1201               closeprog = 1;
1202             }
1203           else if (0 < readsize)
1204             {
1205
1206             }
1207           else
1208             {
1209               //eof
1210               //closeprog = 1;
1211             }
1212         }
1213
1214     }
1215
1216   return 0;
1217
1218 }
1219
1220 int
1221 main(int argc, char *argv[])
1222 {
1223   if (3 != argc)
1224     {
1225       fprintf(
1226           stderr,
1227           "This program must be started with the interface and the operating mode as argument.\n");
1228       usage();
1229       return 1;
1230     }
1231
1232   if (strstr(argv[2], "1") || strstr(argv[2], "2"))
1233     {
1234
1235       return testmode(argc, argv);
1236     }
1237   else
1238     {
1239       hardwaremode(argc, argv);
1240     }
1241
1242 #if 0
1243   u8 u8aSendBuffer[500];
1244   char szErrbuf[PCAP_ERRBUF_SIZE];
1245   int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
1246   int nOrdinal = 0, r, nDelay = 100000;
1247   int nRateIndex = 0, retval, bytes;
1248   pcap_t *ppcap = NULL;
1249   struct bpf_program bpfprogram;
1250   char * szProgram = "", fBrokenSocket = 0;
1251   u16 u16HeaderLen;
1252   char szHostname[PATH_MAX];
1253
1254   if (gethostname(szHostname, sizeof (szHostname) - 1))
1255     {
1256       perror("unable to get hostname");
1257     }
1258   szHostname[sizeof (szHostname) - 1] = '\0';
1259
1260   printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com>  GPL2\n");
1261
1262   while (1)
1263     {
1264       int nOptionIndex;
1265       static const struct option optiona[] =
1266         {
1267             { "delay", required_argument, NULL, 'd'},
1268             { "fcs", no_argument, &flagMarkWithFCS, 1},
1269             { "help", no_argument, &flagHelp, 1},
1270             { "verbose", no_argument, &flagVerbose, 1},
1271             { 0, 0, 0, 0}
1272         };
1273       int c = getopt_long(argc, argv, "d:hf",
1274           optiona, &nOptionIndex);
1275
1276       if (c == -1)
1277       break;
1278       switch (c)
1279         {
1280           case 0: // long option
1281           break;
1282
1283           case 'h': // help
1284           usage();
1285
1286           case 'd': // delay
1287           nDelay = atoi(optarg);
1288           break;
1289
1290           case 'f': // mark as FCS attached
1291           flagMarkWithFCS = 1;
1292           break;
1293
1294           case 'v': //Verbose / readable output to cout
1295           flagVerbose = 1;
1296           break;
1297
1298           default:
1299           printf("unknown switch %c\n", c);
1300           usage();
1301           break;
1302         }
1303     }
1304
1305   if (optind >= argc)
1306   usage();
1307
1308   // open the interface in pcap
1309
1310   szErrbuf[0] = '\0';
1311   ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1312   if (ppcap == NULL)
1313     {
1314       printf("Unable to open interface %s in pcap: %s\n",
1315           argv[optind], szErrbuf);
1316       return (1);
1317     }
1318
1319   //get mac from interface
1320
1321   /*int sock, j, k;
1322    char mac[32];
1323
1324    sock=socket(PF_INET, SOCK_STREAM, 0);
1325    if (-1==sock) {
1326    perror("can not open socket\n");
1327    return 1;
1328    }
1329
1330    if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1331    perror("ioctl(SIOCGIFHWADDR) ");
1332    return 1;
1333    }
1334    for (j=0, k=0; j<6; j++) {
1335    k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
1336    (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
1337    }
1338    mac[sizeof(mac)-1]='\0';
1339    */
1340
1341   //get header type
1342   nLinkEncap = pcap_datalink(ppcap);
1343   nCaptureHeaderLength = 0;
1344
1345   switch (nLinkEncap)
1346     {
1347
1348       case DLT_PRISM_HEADER:
1349       printf("DLT_PRISM_HEADER Encap\n");
1350       nCaptureHeaderLength = 0x40;
1351       n80211HeaderLength = 0x20; // ieee80211 comes after this
1352       szProgram = "radio[0x4a:4]==0x13223344";
1353       break;
1354
1355       case DLT_IEEE802_11_RADIO:
1356       printf("DLT_IEEE802_11_RADIO Encap\n");
1357       nCaptureHeaderLength = 0x40;
1358       n80211HeaderLength = 0x18; // ieee80211 comes after this
1359       szProgram = "ether[0x0a:4]==0x13223344";
1360       break;
1361
1362       default:
1363       printf("!!! unknown encapsulation on %s !\n", argv[1]);
1364       return (1);
1365
1366     }
1367
1368   if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1)
1369     {
1370       puts(szProgram);
1371       puts(pcap_geterr(ppcap));
1372       return (1);
1373     }
1374   else
1375     {
1376       if (pcap_setfilter(ppcap, &bpfprogram) == -1)
1377         {
1378           puts(szProgram);
1379           puts(pcap_geterr(ppcap));
1380         }
1381       else
1382         {
1383           printf("RX Filter applied\n");
1384         }
1385       pcap_freecode(&bpfprogram);
1386     }
1387
1388   pcap_setnonblock(ppcap, 1, szErrbuf);
1389
1390   printf("   (delay between packets %dus)\n", nDelay);
1391
1392   memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer));
1393
1394   while (!fBrokenSocket)
1395     {
1396       u8 * pu8 = u8aSendBuffer;
1397       struct pcap_pkthdr * ppcapPacketHeader = NULL;
1398       struct ieee80211_radiotap_iterator rti;
1399       PENUMBRA_RADIOTAP_DATA prd;
1400       //init of the values
1401       prd.m_nRate = 255;
1402       prd.m_nChannel = 255;
1403       prd.m_nAntenna = 255;
1404       prd.m_nRadiotapFlags = 255;
1405       u8 * pu8Payload = u8aSendBuffer;
1406       int n, nRate;
1407
1408       // receive
1409
1410       retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1411           (const u_char**) &pu8Payload);
1412
1413       if (retval < 0)
1414         {
1415           fBrokenSocket = 1;
1416           continue;
1417         }
1418
1419       if (retval != 1)
1420       goto do_tx;
1421
1422       u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1423
1424       printf("rtap: ");
1425       Dump(pu8Payload, u16HeaderLen);
1426
1427       if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength))
1428       continue;
1429
1430       bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength);
1431       if (bytes < 0)
1432       continue;
1433
1434       if (ieee80211_radiotap_iterator_init(&rti,
1435               (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0)
1436       continue;
1437
1438       while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0)
1439         {
1440
1441           switch (rti.this_arg_index)
1442             {
1443               case IEEE80211_RADIOTAP_RATE:
1444               prd.m_nRate = (*rti.this_arg);
1445               break;
1446
1447               case IEEE80211_RADIOTAP_CHANNEL:
1448               prd.m_nChannel = le16_to_cpu(*((u16 *)rti.this_arg));
1449               prd.m_nChannelFlags = le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
1450               break;
1451
1452               case IEEE80211_RADIOTAP_ANTENNA:
1453               prd.m_nAntenna = (*rti.this_arg) + 1;
1454               break;
1455
1456               case IEEE80211_RADIOTAP_FLAGS:
1457               prd.m_nRadiotapFlags = *rti.this_arg;
1458               break;
1459
1460             }
1461         }
1462
1463       pu8Payload += u16HeaderLen + n80211HeaderLength;
1464
1465       if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
1466       bytes -= 4;
1467
1468       printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
1469           "Ant: %d, Flags: 0x%X\n", prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
1470           prd.m_nChannel / 1000, prd.m_nChannel - ((prd.m_nChannel / 1000)
1471               * 1000), prd.m_nAntenna, prd.m_nRadiotapFlags);
1472
1473       Dump(pu8Payload, bytes);
1474
1475       do_tx:
1476
1477       // transmit
1478
1479       memcpy(u8aSendBuffer, u8aRadiotapHeader, sizeof(u8aRadiotapHeader));
1480       if (flagMarkWithFCS)
1481       pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
1482       nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
1483       if (nRateIndex >= sizeof(u8aRatesToUse))
1484       nRateIndex = 0;
1485       pu8 += sizeof(u8aRadiotapHeader);
1486
1487       memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader));
1488       pu8 += sizeof(u8aIeeeHeader);
1489
1490       pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d"
1491           "broadcast packet"
1492           "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname);
1493       r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1494       if (r != (pu8 - u8aSendBuffer))
1495         {
1496           perror("Trouble injecting packet");
1497           return (1);
1498         }
1499       if (nDelay)
1500       usleep(nDelay);
1501     }
1502
1503 #endif
1504   return (0);
1505 }
1506