2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
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.
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.
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.
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
27 * This program serves as the mediator between the wlan interface and
31 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
38 #include <netpacket/packet.h>
39 #include <linux/if_ether.h>
41 #include <linux/wireless.h>
42 #include <netinet/in.h>
43 #include <linux/if_tun.h>
52 //#include <sys/utsname.h>
53 #include <sys/param.h>
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"
78 #include "wlan/radiotap-parser.h"
79 /* radiotap-parser defines types like u8 that
80 * ieee80211_radiotap.h needs
82 * we use our local copy of ieee80211_radiotap.h
84 * - since we can't support extensions we don't understand
85 * - since linux does not include it in userspace headers
87 #include "wlan/ieee80211_radiotap.h"
88 #include "wlan/crctable_osdep.h"
89 #include "wlan/loopback_helper.h"
90 #include "wlan/ieee80211.h"
92 #define ARPHRD_IEEE80211 801
93 #define ARPHRD_IEEE80211_PRISM 802
94 #define ARPHRD_IEEE80211_FULL 803
98 #include "wlan/helper_common.h"
99 #include "wlan/loopback_helper.h"
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" };
128 struct Hardware_Infos
131 struct sendbuf *write_pout;
132 int fd_in, arptype_in;
138 DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */
142 //struct pcap_file_header pfh_in;
149 //char *wlanctlng; /* XXX never set */
155 unsigned char pl_mac[6];
159 //#include "radiotap.h"
163 { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 };
165 /* wifi bitrate to use in 500kHz units */
168 static const u8 u8aRatesToUse[] =
171 54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5
174 #define OFFSET_FLAGS 0x10
175 #define OFFSET_RATE 0x11
177 // this is where we store a summary of the
178 // information from the radiotap header
187 int m_nRadiotapFlags;
188 }__attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
198 Dump(u8 * pu8, int nLength)
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;
207 for (n = 0; n < nLength; n++)
209 baaLast[(nLine & 1) ^ 1][n & 0xf] = pu8[n];
210 if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
211 szChar[n & 0xf] = '.';
213 szChar[n & 0xf] = pu8[n];
214 szChar[(n & 0xf) + 1] = '\0';
215 nPos += sprintf(&sz[nPos], "%02X ", baaLast[(nLine & 1) ^ 1][n & 0xf]);
218 if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst))
225 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
226 buf += sprintf(buf, "%04x: %s %s\n", nStart, sz, szChar);
239 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
241 buf += sprintf(buf, "%04x: %s", nStart, sz);
247 buf += sprintf(buf, " ");
251 buf += sprintf(buf, "%s\n", szChar);
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"
266 calc_crc_osdep(unsigned char * buf, int len)
268 unsigned long crc = 0xFFFFFFFF;
270 for (; len > 0; len--, buf++)
271 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
276 /* CRC checksum verification routine */
279 check_crc_buf_osdep(unsigned char *buf, int len)
286 crc = calc_crc_osdep(buf, len);
288 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc
289 >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
292 /* Search a file recursively */
295 searchInside(const char * dir, const char * filename)
310 len = strlen(filename);
311 lentot = strlen(dir) + 256 + 2;
312 curfile = (char *) calloc(1, lentot);
314 while ((ep = readdir(dp)) != NULL)
317 memset(curfile, 0, lentot);
318 sprintf(curfile, "%s/%s", dir, ep->d_name);
320 //Checking if it's the good file
321 if ((int) strlen(ep->d_name) == len && !strcmp(ep->d_name, filename))
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))
331 //Check if the directory isn't "." or ".."
332 if (strcmp(".", ep->d_name) && strcmp("..", ep->d_name))
335 ret = searchInside(curfile, filename);
350 /* Search a wireless tool and return its path */
353 wiToolsPath(const char * tool)
357 static const char * paths[] =
358 { "/sbin", "/usr/sbin", "/usr/local/sbin", "/bin", "/usr/bin",
359 "/usr/local/bin", "/tmp" };
361 nbelems = sizeof(paths) / sizeof(char *);
363 for (i = 0; i < nbelems; i++)
365 path = searchInside(paths[i], tool);
375 linux_get_channel(struct Hardware_Infos *dev)
381 memset(&wrq, 0, sizeof(struct iwreq));
385 strncpy(wrq.ifr_name, dev->main_if, IFNAMSIZ );
387 strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ );
391 if (dev->drivertype == DT_IPW2200)
394 if (ioctl(fd, SIOCGIWFREQ, &wrq) < 0)
397 frequency = wrq.u.freq.m;
398 if (frequency > 100000000)
400 else if (frequency > 1000000)
403 if (frequency > 1000)
404 chan = getChannelFromFrequency(frequency);
412 linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count,
413 struct Radiotap_rx * ri)
415 unsigned char tmpbuf[4096 * 4];
417 int caplen, n, got_signal, got_noise, got_channel, fcs_removed;
419 caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0;
421 if ((unsigned) count > sizeof(tmpbuf))
423 caplen = read(dev->fd_in, tmpbuf, count);
429 perror("read failed");
433 memset(buf, 0, sizeof(buf));
437 memset(ri, 0, sizeof(*ri));
439 if (dev->arptype_in == ARPHRD_IEEE80211_PRISM)
441 /* skip the prism header */
442 if (tmpbuf[7] == 0x40)
444 /* prism54 uses a different format */
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;
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;
472 n = *(int *) (tmpbuf + 4);
475 if (n < 8 || n >= caplen)
479 if (dev->arptype_in == ARPHRD_IEEE80211_FULL)
481 struct ieee80211_radiotap_iterator iterator;
482 struct ieee80211_radiotap_header *rthdr;
484 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
486 if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0)
489 /* go through the radiotap arguments we have been given
493 while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0))
496 switch (iterator.this_arg_index)
499 case IEEE80211_RADIOTAP_TSFT:
500 ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg));
503 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
506 if (*iterator.this_arg < 127)
507 ri->ri_power = *iterator.this_arg;
509 ri->ri_power = *iterator.this_arg - 255;
515 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
518 if (*iterator.this_arg < 127)
519 ri->ri_power = *iterator.this_arg;
521 ri->ri_power = *iterator.this_arg - 255;
527 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
530 if (*iterator.this_arg < 127)
531 ri->ri_noise = *iterator.this_arg;
533 ri->ri_noise = *iterator.this_arg - 255;
539 case IEEE80211_RADIOTAP_DB_ANTNOISE:
542 if (*iterator.this_arg < 127)
543 ri->ri_noise = *iterator.this_arg;
545 ri->ri_noise = *iterator.this_arg - 255;
551 case IEEE80211_RADIOTAP_ANTENNA:
552 ri->ri_antenna = *iterator.this_arg;
555 case IEEE80211_RADIOTAP_CHANNEL:
556 ri->ri_channel = *iterator.this_arg;
560 case IEEE80211_RADIOTAP_RATE:
561 ri->ri_rate = (*iterator.this_arg) * 500000;
564 case IEEE80211_RADIOTAP_FLAGS:
565 /* is the CRC visible at the end?
568 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
574 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
582 n = le16_to_cpu(rthdr->it_len);
584 if (n <= 0 || n >= caplen)
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)
596 memcpy(buf, tmpbuf + n, caplen);
598 if (ri && !got_channel)
599 ri->ri_channel = linux_get_channel(dev);
605 linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count)
609 //unsigned short int *p_rtlen;
611 //unsigned char * u8aRadiotap = buf;
613 /* Pointer to the radiotap header length field for later use. */
614 //p_rtlen = (unsigned short int*) (u8aRadiotap + 2);
616 ret = write(dev->fd_out, buf, count);
620 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
627 perror("write failed");
631 /* radiotap header length is stored little endian on all systems */
633 ret -= letoh16(*p_rtlen);
637 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno
644 perror("write failed");
652 openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype,
657 struct packet_mreq mr;
658 struct sockaddr_ll sll;
660 /* find the interface index */
662 memset(&ifr, 0, sizeof(ifr));
663 strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1);
665 if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)
667 printf("Interface %s: \n", iface);
668 perror("ioctl(SIOCGIFINDEX) failed");
672 memset(&sll, 0, sizeof(sll));
673 sll.sll_family = AF_PACKET;
674 sll.sll_ifindex = ifr.ifr_ifindex;
676 sll.sll_protocol = htons(ETH_P_ALL);
678 /* lookup the hardware type */
680 if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
682 printf("Interface %s: \n", iface);
683 perror("ioctl(SIOCGIFHWADDR) failed");
688 memset(&wrq, 0, sizeof(struct iwreq));
689 strncpy(wrq.ifr_name, iface, IFNAMSIZ);
691 if (ioctl(fd, SIOCGIWMODE, &wrq) < 0)
693 /* most probably not supported (ie for rtap ipw interface) *
694 * so just assume its correctly set... */
695 wrq.u.mode = IW_MODE_MONITOR;
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))
702 printf("Error: %s not in monitor mode\n", iface);
706 /* Is interface st to up, broadcast & running ? */
707 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
709 /* Bring interface up*/
710 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
712 if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0)
714 perror("ioctl(SIOCSIFFLAGS) failed");
718 /* bind the raw socket to the interface */
720 if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) < 0)
722 printf("Interface %s: \n", iface);
723 perror("bind(ETH_P_ALL) failed");
727 /* lookup the hardware type */
729 if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
731 printf("Interface %s: \n", iface);
732 perror("ioctl(SIOCGIFHWADDR) failed");
736 memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6);
738 *arptype = ifr.ifr_hwaddr.sa_family;
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)
744 if (ifr.ifr_hwaddr.sa_family == 1)
745 fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) ");
747 fprintf(stderr, "\nUnsupported hardware link type %4d ",
748 ifr.ifr_hwaddr.sa_family);
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);
758 /* enable promiscuous mode */
760 memset(&mr, 0, sizeof(mr));
761 mr.mr_ifindex = sll.sll_ifindex;
762 mr.mr_type = PACKET_MR_PROMISC;
764 if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0)
766 perror("setsockopt(PACKET_MR_PROMISC) failed");
774 wlaninit(struct Hardware_Infos * dev, char *iface)
779 //dev->inject_wlanng = 1;
780 //dev->rate = 2; /* default to 1Mbps if nothing is set */
784 dev->fd_in = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
787 perror("socket(PF_PACKET) failed at fd_in");
789 fprintf(stderr, "This program requires root privileges.\n");
794 dev->fd_main = socket(PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
795 if (0 > dev->fd_main)
797 perror("socket(PF_PACKET) failed at fd_main");
799 fprintf(stderr, "This program requires root privileges.\n");
803 /* Check iwpriv existence */
805 iwpriv = wiToolsPath("iwpriv");
806 dev->iwpriv = iwpriv;
807 dev->iwconfig = wiToolsPath("iwconfig");
808 dev->ifconfig = wiToolsPath("ifconfig");
812 fprintf(stderr, "Can't find wireless tools, exiting.\n");
816 dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
819 perror("socket(PF_PACKET) failed at fd_out");
823 /* figure out device type */
825 /* mac80211 radiotap injection
826 * detected based on interface called mon...
827 * since mac80211 allows multiple virtual interfaces
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
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);
839 if (system(strbuf) == 0)
840 dev->drivertype = DT_MAC80211_RT;
844 // At the moment only mac80211 tested
845 fprintf(stderr, "only mac80211 stack supported, exiting.\n");
850 fprintf(stderr, "Interface %s -> driver: %s\n", iface,
851 szaDriverTypes[dev->drivertype]);
854 if (openraw(dev, iface, dev->fd_out, &dev->arptype_in, dev->pl_mac) != 0)
859 dev->fd_in = dev->fd_out;
860 dev->iface = GNUNET_malloc(sizeof(char) *6);
861 strncpy(dev->iface, iface, sizeof(char) * 6);
863 //dev->arptype_out = dev->arptype_in;
866 close_out: close(dev->fd_out);
867 close_in: close(dev->fd_in);
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
879 mac_test(unsigned char * buf, struct Hardware_Infos * dev)
881 struct ieee80211_frame * u8aIeeeHeader;
882 u8aIeeeHeader = (struct ieee80211_frame *) buf;
883 if (0 == memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, 6))
885 if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, 6))
890 if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, 6))
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
906 mac_set(unsigned char * buf, struct Hardware_Infos * dev)
908 struct ieee80211_frame * u8aIeeeHeader;
909 u8aIeeeHeader = (struct ieee80211_frame *) buf;
911 u8aIeeeHeader->i_fc[0] = 0x08;
912 u8aIeeeHeader->i_fc[1] = 0x00;
914 memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6);
915 memcpy(u8aIeeeHeader->i_addr3, &mac_bssid, 6);
920 stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
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;
929 unsigned char u8aRadiotap[] =
930 { 0x00, 0x00, // <-- radiotap version
931 0x0c, 0x00, // <- radiotap header length
932 0x04, 0x80, 0x00, 0x00, // <-- bitmap
934 0x00, // <-- padding for natural alignment
935 0x18, 0x00, // <-- TX flags
938 sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send)
939 - sizeof(struct GNUNET_MessageHeader);
941 if ((sendsize) > MAXLINE * 2)
943 fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
947 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
949 fprintf(stderr, "Function stdin_send: wrong packet type\n");
953 if (sendsize < sizeof(struct ieee80211_frame)
954 + sizeof(struct GNUNET_MessageHeader))
956 fprintf(stderr, "Function stdin_send: packet too small\n");
960 u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
961 u8aRadiotap[8] = header->rate;
963 switch (dev->drivertype)
967 memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap));
968 memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize);
970 wlanheader = write_pout->buf + sizeof(u8aRadiotap);
971 mac_set(wlanheader, dev);
973 sendsize += sizeof(u8aRadiotap);
980 write_pout->size = sendsize;
984 maketest(unsigned char * buf, struct Hardware_Infos * dev)
987 static uint16_t seqenz = 0;
988 static int first = 0;
990 const int rate = 11000000;
993 "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
995 unsigned char u8aRadiotap[] =
996 { 0x00, 0x00, // <-- radiotap version
997 0x00, 0x00, // <- radiotap header length
998 0x04, 0x80, 0x02, 0x00, // <-- bitmap
1000 0x00, // <-- padding for natural alignment
1001 0x10, 0x00, // <-- TX flags
1005 /*uint8_t u8aRadiotap[] =
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
1019 u8aRadiotap[8] = (rate / 500000);
1020 u8aRadiotap[2] = htole16(sizeof(u8aRadiotap));
1022 static struct ieee80211_frame u8aIeeeHeader;
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
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
1039 memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame));
1040 memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6);
1044 tmp16 = (uint16_t*) u8aIeeeHeader.i_dur;
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);
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);
1060 hardwaremode(int argc, char *argv[])
1064 struct Hardware_Infos dev;
1065 //struct ifreq ifreq;
1066 struct Radiotap_rx * rxinfo;
1067 uint8_t * mac = dev.pl_mac;
1070 struct GNUNET_MessageHeader * header;
1072 signal(SIGINT, &sigfunc_hw);
1073 signal(SIGTERM, &sigfunc_hw);
1075 if (wlaninit(&dev, argv[1]))
1081 //if (0 != setresuid(uid, uid, uid))
1083 // fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1084 /* not critical, continue anyway */
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]);*/
1093 unsigned char * datastart;
1094 char readbuf[MAXLINE];
1096 struct sendbuf write_std;
1100 struct sendbuf write_pout;
1101 write_pout.size = 0;
1104 dev.write_pout = &write_pout;
1114 struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
1117 fdpout = dev.fd_out;
1119 stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev);
1123 write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac);
1128 retval = select(0, NULL, NULL, NULL, &tv);
1130 while (0 == closeprog)
1133 //write_pout.size = maketest(write_pout.buf, &dev);
1136 //select(0, NULL, NULL, NULL, &tv);
1145 // if output queue is empty
1146 if (0 == write_pout.size)
1148 FD_SET(STDIN_FILENO, &rfds);
1151 if (0 == write_std.size)
1153 FD_SET(fdpin, &rfds);
1157 // if there is something to write
1158 if (0 < write_std.size)
1160 FD_SET(STDOUT_FILENO, &wfds);
1161 maxfd = MAX(maxfd, STDOUT_FILENO);
1164 if (0 < write_pout.size)
1166 FD_SET(fdpout, &wfds);
1167 maxfd = MAX(maxfd, fdpout);
1170 retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
1172 if (-1 == retval && EINTR == errno)
1178 fprintf(stderr, "select failed: %s\n", strerror(errno));
1182 if (FD_ISSET(STDOUT_FILENO, &wfds))
1184 ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
1185 write_std.size - write_std.pos);
1190 fprintf(stderr, "Write ERROR to STDOUT\n");
1195 write_std.pos += ret;
1196 // check if finished
1197 if (write_std.pos == write_std.size)
1205 if (FD_ISSET(fdpout, &wfds))
1208 ret = linux_write(&dev, write_pout.buf, write_pout.size);
1213 fprintf(stderr, "Write ERROR to fdpout\n");
1217 write_pout.pos += ret;
1218 // check if finished
1219 if (write_pout.pos != write_pout.size && ret != 0)
1223 "Write ERROR packet not in one piece send: %u, %u\n",
1224 write_pout.pos, write_pout.size);
1226 else if (write_pout.pos == write_pout.size)
1229 write_pout.size = 0;
1235 if (FD_ISSET(STDIN_FILENO, &rfds))
1237 readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
1242 fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
1244 else if (0 < readsize)
1246 GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
1247 GNUNET_NO, GNUNET_NO);
1257 if (FD_ISSET(fdpin, &rfds))
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);
1265 readsize = linux_read(&dev, datastart, sizeof(write_std.buf)
1266 - sizeof(struct Radiotap_rx)
1267 - sizeof(struct GNUNET_MessageHeader), rxinfo);
1272 fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
1275 else if (0 < readsize)
1277 if (1 == mac_test(datastart, &dev))
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);
1305 GNUNET_SERVER_mst_destroy(stdin_mst);
1308 end: GNUNET_SERVER_mst_destroy(stdin_mst);
1314 main(int argc, char *argv[])
1321 "This program must be started with the interface and the operating mode as argument.\n");
1326 if (strstr(argv[2], "1") || strstr(argv[2], "2"))
1329 ret = testmode(argc, argv);
1334 ret = hardwaremode(argc, argv);
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;
1347 char szHostname[PATH_MAX];
1349 if (gethostname(szHostname, sizeof (szHostname) - 1))
1351 perror("unable to get hostname");
1353 szHostname[sizeof (szHostname) - 1] = '\0';
1355 printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
1360 static const struct option optiona[] =
1362 { "delay", required_argument, NULL, 'd'},
1363 { "fcs", no_argument, &flagMarkWithFCS, 1},
1364 { "help", no_argument, &flagHelp, 1},
1365 { "verbose", no_argument, &flagVerbose, 1},
1368 int c = getopt_long(argc, argv, "d:hf",
1369 optiona, &nOptionIndex);
1375 case 0: // long option
1382 nDelay = atoi(optarg);
1385 case 'f': // mark as FCS attached
1386 flagMarkWithFCS = 1;
1389 case 'v': //Verbose / readable output to cout
1394 printf("unknown switch %c\n", c);
1403 // open the interface in pcap
1406 ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
1409 printf("Unable to open interface %s in pcap: %s\n",
1410 argv[optind], szErrbuf);
1414 //get mac from interface
1419 sock=socket(PF_INET, SOCK_STREAM, 0);
1421 perror("can not open socket\n");
1425 if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
1426 perror("ioctl(SIOCGIFHWADDR) ");
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]);
1433 mac[sizeof(mac)-1]='\0';
1437 nLinkEncap = pcap_datalink(ppcap);
1438 nCaptureHeaderLength = 0;
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";
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";
1458 printf("!!! unknown encapsulation on %s !\n", argv[1]);
1463 if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1)
1466 puts(pcap_geterr(ppcap));
1471 if (pcap_setfilter(ppcap, &bpfprogram) == -1)
1474 puts(pcap_geterr(ppcap));
1478 printf("RX Filter applied\n");
1480 pcap_freecode(&bpfprogram);
1483 pcap_setnonblock(ppcap, 1, szErrbuf);
1485 printf(" (delay between packets %dus)\n", nDelay);
1487 memset(u8aSendBuffer, 0, sizeof(u8aSendBuffer));
1489 while (!fBrokenSocket)
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
1497 prd.m_nChannel = 255;
1498 prd.m_nAntenna = 255;
1499 prd.m_nRadiotapFlags = 255;
1500 u8 * pu8Payload = u8aSendBuffer;
1505 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
1506 (const u_char**) &pu8Payload);
1517 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
1520 Dump(pu8Payload, u16HeaderLen);
1522 if (ppcapPacketHeader->len < (u16HeaderLen + n80211HeaderLength))
1525 bytes = ppcapPacketHeader->len - (u16HeaderLen + n80211HeaderLength);
1529 if (ieee80211_radiotap_iterator_init(&rti,
1530 (struct ieee80211_radiotap_header *) pu8Payload, bytes) < 0)
1533 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0)
1536 switch (rti.this_arg_index)
1538 case IEEE80211_RADIOTAP_RATE:
1539 prd.m_nRate = (*rti.this_arg);
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)));
1547 case IEEE80211_RADIOTAP_ANTENNA:
1548 prd.m_nAntenna = (*rti.this_arg) + 1;
1551 case IEEE80211_RADIOTAP_FLAGS:
1552 prd.m_nRadiotapFlags = *rti.this_arg;
1558 pu8Payload += u16HeaderLen + n80211HeaderLength;
1560 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
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);
1568 Dump(pu8Payload, bytes);
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))
1580 pu8 += sizeof(u8aRadiotapHeader);
1582 memcpy(pu8, u8aIeeeHeader, sizeof(u8aIeeeHeader));
1583 pu8 += sizeof(u8aIeeeHeader);
1585 pu8 += sprintf((char *) u8aSendBuffer, "Packetspammer %02d"
1587 "#%05d -- :-D --%s ----", nRate / 2, nOrdinal++, szHostname);
1588 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
1589 if (r != (pu8 - u8aSendBuffer))
1591 perror("Trouble injecting packet");
1601 maketest(NULL, NULL);