2 This file is part of GNUnet.
3 (C) 2010, 2011 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
32 * parts taken from aircrack-ng, parts changend.
36 #include <sys/socket.h>
37 #include <sys/ioctl.h>
38 #include <sys/types.h>
43 #include <netpacket/packet.h>
44 #include <linux/if_ether.h>
46 #include <linux/wireless.h>
47 #include <netinet/in.h>
48 #include <linux/if_tun.h>
56 //#include <sys/utsname.h>
57 #include <sys/param.h>
65 //#include "platform.h"
66 #include "gnunet_constants.h"
67 #include "gnunet_os_lib.h"
68 #include "gnunet_transport_plugin.h"
69 #include "transport.h"
70 #include "gnunet_util_lib.h"
71 #include "plugin_transport_wlan.h"
72 #include "gnunet_common.h"
73 #include "gnunet-transport-wlan-helper.h"
74 #include "gnunet_crypto_lib.h"
76 #include "wlan/radiotap-parser.h"
77 /* radiotap-parser defines types like u8 that
78 * ieee80211_radiotap.h needs
80 * we use our local copy of ieee80211_radiotap.h
82 * - since we can't support extensions we don't understand
83 * - since linux does not include it in userspace headers
85 #include "wlan/ieee80211_radiotap.h"
86 #include "wlan/crctable_osdep.h"
87 //#include "wlan/loopback_helper.h"
88 //#include "wlan/ieee80211.h"
89 #include "wlan/helper_common.h"
91 #define ARPHRD_IEEE80211 801
92 #define ARPHRD_IEEE80211_PRISM 802
93 #define ARPHRD_IEEE80211_FULL 803
97 #define MAC_ADDR_SIZE 6
100 #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
103 * generic definitions for IEEE 802.11 frames
105 struct ieee80211_frame
109 u_int8_t i_addr1[IEEE80211_ADDR_LEN];
110 u_int8_t i_addr2[IEEE80211_ADDR_LEN];
111 u_int8_t i_addr3[IEEE80211_ADDR_LEN];
113 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
118 * struct for storing the information of the hardware
120 struct Hardware_Infos
126 struct sendbuf write_pout;
128 * file descriptor for the raw socket
135 * Name of the interface, not necessarily 0-terminated (!).
137 char iface[IFNAMSIZ];
138 unsigned char pl_mac[MAC_ADDR_SIZE];
141 struct RadioTapheader
143 struct ieee80211_radiotap_header header;
151 getChannelFromFrequency (int frequency);
153 // FIXME: make nice...
155 * function to calculate the crc, the start of the calculation
156 * @param buf buffer to calc the crc
157 * @param len len of the buffer
161 calc_crc_osdep (unsigned char *buf, int len)
163 unsigned long crc = 0xFFFFFFFF;
165 for (; len > 0; len--, buf++)
166 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
171 /* CRC checksum verification routine */
173 // FIXME: make nice...
175 * Function to check crc of the wlan packet
176 * @param buf buffer of the packet
177 * @param len len of the data
178 * @return crc sum of the data
181 check_crc_buf_osdep (unsigned char *buf, int len)
188 crc = calc_crc_osdep (buf, len);
190 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
191 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
195 // FIXME: make nice...
197 * function to get the channel of a specific wlan card
198 * @param dev pointer to the dev struct of the card
199 * @return channel number
202 linux_get_channel (struct Hardware_Infos *dev)
208 memset (&wrq, 0, sizeof (struct iwreq));
210 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
213 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
216 frequency = wrq.u.freq.m;
217 if (100000000 < frequency)
219 else if (1000000 < frequency)
222 if (1000 < frequency)
223 chan = getChannelFromFrequency (frequency);
231 // FIXME: make nice...
233 * function to read from a wlan card
234 * @param dev pointer to the struct of the wlan card
235 * @param buf buffer to read to
236 * @param buf_size size of the buffer
237 * @param ri radiotap_rx info
238 * @return size read from the buffer
241 linux_read (struct Hardware_Infos *dev, unsigned char *buf, /* FIXME: void*? */
242 size_t buf_size, struct Radiotap_rx *ri)
244 unsigned char tmpbuf[buf_size];
246 int n, got_signal, got_noise, got_channel, fcs_removed;
248 n = got_signal = got_noise = got_channel = fcs_removed = 0;
250 caplen = read (dev->fd_raw, tmpbuf, buf_size);
255 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
259 memset (buf, 0, buf_size);
260 memset (ri, 0, sizeof (*ri));
262 switch (dev->arptype_in)
264 case ARPHRD_IEEE80211_PRISM:
266 /* skip the prism header */
267 if (tmpbuf[7] == 0x40)
269 /* prism54 uses a different format */
270 ri->ri_power = tmpbuf[0x33];
271 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
272 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
279 ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48);
280 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
281 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
282 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
283 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
287 n = *(int *) (tmpbuf + 4);
290 if (n < 8 || n >= caplen)
295 case ARPHRD_IEEE80211_FULL:
297 struct ieee80211_radiotap_iterator iterator;
298 struct ieee80211_radiotap_header *rthdr;
300 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
302 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
305 /* go through the radiotap arguments we have been given
309 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
312 switch (iterator.this_arg_index)
315 case IEEE80211_RADIOTAP_TSFT:
316 ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg));
319 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
322 if (*iterator.this_arg < 127)
323 ri->ri_power = *iterator.this_arg;
325 ri->ri_power = *iterator.this_arg - 255;
331 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
334 if (*iterator.this_arg < 127)
335 ri->ri_power = *iterator.this_arg;
337 ri->ri_power = *iterator.this_arg - 255;
343 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
346 if (*iterator.this_arg < 127)
347 ri->ri_noise = *iterator.this_arg;
349 ri->ri_noise = *iterator.this_arg - 255;
355 case IEEE80211_RADIOTAP_DB_ANTNOISE:
358 if (*iterator.this_arg < 127)
359 ri->ri_noise = *iterator.this_arg;
361 ri->ri_noise = *iterator.this_arg - 255;
367 case IEEE80211_RADIOTAP_ANTENNA:
368 ri->ri_antenna = *iterator.this_arg;
371 case IEEE80211_RADIOTAP_CHANNEL:
372 ri->ri_channel = *iterator.this_arg;
376 case IEEE80211_RADIOTAP_RATE:
377 ri->ri_rate = (*iterator.this_arg) * 500000;
380 case IEEE80211_RADIOTAP_FLAGS:
381 /* is the CRC visible at the end?
384 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
390 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
396 n = le16_to_cpu (rthdr->it_len);
397 if (n <= 0 || n >= caplen)
401 case ARPHRD_IEEE80211:
411 //detect fcs at the end, even if the flag wasn't set and remove it
412 if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
416 memcpy (buf, tmpbuf + n, caplen);
418 ri->ri_channel = linux_get_channel (dev);
424 * function to open the device for read/write
425 * @param dev pointer to the device struct
426 * @return 0 on success
429 openraw (struct Hardware_Infos *dev)
433 struct packet_mreq mr;
434 struct sockaddr_ll sll;
436 /* find the interface index */
437 memset (&ifr, 0, sizeof (ifr));
438 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
439 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
442 "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
443 IFNAMSIZ, dev->iface, strerror (errno));
447 /* lookup the hardware type */
448 memset (&sll, 0, sizeof (sll));
449 sll.sll_family = AF_PACKET;
450 sll.sll_ifindex = ifr.ifr_ifindex;
451 sll.sll_protocol = htons (ETH_P_ALL);
452 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
454 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
455 IFNAMSIZ, dev->iface, strerror (errno));
460 memset (&wrq, 0, sizeof (struct iwreq));
461 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
462 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
464 /* most probably not supported (ie for rtap ipw interface) *
465 * so just assume its correctly set... */
466 wrq.u.mode = IW_MODE_MONITOR;
469 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
470 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
471 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
472 (wrq.u.mode != IW_MODE_MONITOR))
474 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
475 IFNAMSIZ, dev->iface);
479 /* Is interface st to up, broadcast & running ? */
480 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
482 /* Bring interface up */
483 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
485 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
488 "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
489 IFNAMSIZ, dev->iface, strerror (errno));
494 /* bind the raw socket to the interface */
495 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
497 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
498 dev->iface, strerror (errno));
502 /* lookup the hardware type */
503 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
506 "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
507 IFNAMSIZ, dev->iface, strerror (errno));
511 memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
512 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
513 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
514 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
515 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
517 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
518 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
522 /* enable promiscuous mode */
523 memset (&mr, 0, sizeof (mr));
524 mr.mr_ifindex = sll.sll_ifindex;
525 mr.mr_type = PACKET_MR_PROMISC;
527 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
530 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
531 IFNAMSIZ, dev->iface);
539 * function to prepare the helper, e.g. sockets, device...
540 * @param dev struct for the device
541 * @param iface name of the interface
542 * @return 0 on success
545 wlaninit (struct Hardware_Infos *dev, const char *iface)
551 dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
554 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
557 if (dev->fd_raw >= FD_SETSIZE)
559 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
560 dev->fd_raw, FD_SETSIZE);
565 /* mac80211 stack detection */
567 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
569 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
571 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
575 strncpy (dev->iface, iface, IFNAMSIZ);
576 if (0 != openraw (dev))
586 * Function to test incoming packets mac for being our own.
588 * @param u8aIeeeHeader buffer of the packet
589 * @param dev the Hardware_Infos struct
590 * @return 0 if mac belongs to us, 1 if mac is for another target
593 mac_test (const struct ieee80211_frame *u8aIeeeHeader,
594 const struct Hardware_Infos *dev)
596 if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
598 if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE))
600 if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
607 * function to set the wlan header to make attacks more difficult
608 * @param u8aIeeeHeader pointer to the header of the packet
609 * @param dev pointer to the Hardware_Infos struct
612 mac_set (struct ieee80211_frame *u8aIeeeHeader,
613 const struct Hardware_Infos *dev)
615 u8aIeeeHeader->i_fc[0] = 0x08;
616 u8aIeeeHeader->i_fc[1] = 0x00;
617 memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
618 memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
623 * function to process the data from the stdin
624 * @param cls pointer to the device struct
625 * @param client not used
626 * @param hdr pointer to the start of the packet
629 stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
631 struct Hardware_Infos *dev = cls;
632 struct sendbuf *write_pout = &dev->write_pout;
633 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
634 struct ieee80211_frame *wlanheader;
637 // struct? // FIXME: make nice...
638 struct RadioTapheader rtheader;
640 rtheader.header.it_version = 0;
641 rtheader.header.it_len = htole16 (0x0c);
642 rtheader.header.it_present = htole32 (0x00008004);
643 rtheader.rate = 0x00;
644 rtheader.pad1 = 0x00;
646 htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
648 /* { 0x00, 0x00, <-- radiotap version
649 * 0x0c, 0x00, <- radiotap header length
650 * 0x04, 0x80, 0x00, 0x00, <-- bitmap
652 * 0x00, <-- padding for natural alignment
653 * 0x18, 0x00, <-- TX flags
656 sendsize = ntohs (hdr->size);
658 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
660 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
664 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
666 if (MAXLINE < sendsize)
668 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
671 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
673 fprintf (stderr, "Function stdin_send: wrong packet type\n");
677 rtheader.header.it_len = htole16 (sizeof (rtheader));
678 rtheader.rate = header->rate;
679 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
680 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
681 /* payload contains MAC address, but we don't trust it, so we'll
682 * overwrite it with OUR MAC address again to prevent mischief */
683 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
684 mac_set (wlanheader, dev);
685 write_pout->size = sendsize + sizeof (rtheader);
690 * Function to make test packets with special options
691 * @param buf buffer to write the data to
692 * @param dev device to send the data from
693 * @return size of packet (what should be send)
696 maketest (unsigned char *buf, struct Hardware_Infos *dev)
699 static uint16_t seqenz = 0;
700 static int first = 0;
702 const int rate = 11000000;
703 static const char txt[] =
704 "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
706 unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version
707 0x00, 0x00, // <- radiotap header length
708 0x04, 0x80, 0x02, 0x00, // <-- bitmap
710 0x00, // <-- padding for natural alignment
711 0x10, 0x00, // <-- TX flags
715 /*uint8_t u8aRadiotap[] =
717 * 0x00, 0x00, // <-- radiotap version
718 * 0x19, 0x00, // <- radiotap header length
719 * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
720 * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
721 * 0x00, // <-- flags (Offset +0x10)
722 * 0x6c, // <-- rate (0ffset +0x11)
723 * 0x71, 0x09, 0xc0, 0x00, // <-- channel
724 * 0xde, // <-- antsignal
725 * 0x00, // <-- antnoise
726 * 0x01, // <-- antenna
729 u8aRadiotap[8] = (rate / 500000);
730 u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
732 static struct ieee80211_frame u8aIeeeHeader;
734 uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
735 // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
736 // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
737 0x00, 0x00, // Duration/ID
739 //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
740 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
741 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
742 //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
743 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
744 0x10, 0x86, //Sequence Control
748 memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
749 memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
753 tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
756 htole16 ((sizeof (txt) +
757 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
758 tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
760 (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
761 IEEE80211_SEQ_SEQ_SHIFT);
764 memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
765 memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
766 memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
768 return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
775 * Function to start the hardware for the wlan helper
776 * @param argc number of arguments
777 * @param argv arguments
778 * @return returns one on error
781 hardwaremode (int argc, char *argv[])
784 struct Hardware_Infos dev;
785 char readbuf[MAXLINE];
786 struct sendbuf write_std;
793 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
795 if (0 != wlaninit (&dev, argv[1]))
798 if (0 != setresuid (uid, uid, uid))
800 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
801 /* not critical, continue anyway */
804 dev.write_pout.size = 0;
805 dev.write_pout.pos = 0;
806 stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
808 /* send mac to STDOUT first */
810 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac);
817 if ((0 == dev.write_pout.size) && (1 == stdin_open))
819 FD_SET (STDIN_FILENO, &rfds);
820 maxfd = MAX (maxfd, STDIN_FILENO);
822 if (0 == write_std.size)
824 FD_SET (dev.fd_raw, &rfds);
825 maxfd = MAX (maxfd, dev.fd_raw);
828 if (0 < write_std.size)
830 FD_SET (STDOUT_FILENO, &wfds);
831 maxfd = MAX (maxfd, STDOUT_FILENO);
833 if (0 < dev.write_pout.size)
835 FD_SET (dev.fd_raw, &wfds);
836 maxfd = MAX (maxfd, dev.fd_raw);
838 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
839 if ((-1 == retval) && (EINTR == errno))
843 fprintf (stderr, "select failed: %s\n", strerror (errno));
847 if (FD_ISSET (STDOUT_FILENO, &wfds))
850 write (STDOUT_FILENO, write_std.buf + write_std.pos,
851 write_std.size - write_std.pos);
854 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
857 write_std.pos += ret;
858 if (write_std.pos == write_std.size)
865 if (FD_ISSET (dev.fd_raw, &wfds))
867 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
871 "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n",
872 __LINE__, strerror (errno), dev.write_pout.size);
875 dev.write_pout.pos += ret;
876 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
878 fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n",
879 __LINE__, dev.write_pout.pos, dev.write_pout.size);
882 if (dev.write_pout.pos == dev.write_pout.size)
884 dev.write_pout.pos = 0;
885 dev.write_pout.size = 0;
889 if (FD_ISSET (STDIN_FILENO, &rfds))
891 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
894 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
899 /* stop reading... */
902 GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
906 if (FD_ISSET (dev.fd_raw, &rfds))
908 struct GNUNET_MessageHeader *header;
909 struct Radiotap_rx *rxinfo;
910 struct ieee80211_frame *datastart;
912 header = (struct GNUNET_MessageHeader *) write_std.buf;
913 rxinfo = (struct Radiotap_rx *) &header[1];
914 datastart = (struct ieee80211_frame *) &rxinfo[1];
916 linux_read (&dev, (unsigned char *) datastart,
917 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
918 sizeof (struct GNUNET_MessageHeader), rxinfo);
921 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
924 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
927 ret + sizeof (struct GNUNET_MessageHeader) +
928 sizeof (struct Radiotap_rx);
929 header->size = htons (write_std.size);
930 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
935 /* Error handling, try to clean up a bit at least */
936 GNUNET_SERVER_mst_destroy (stdin_mst);
942 * main function of the helper
943 * @param argc number of arguments
944 * @param argv arguments
945 * @return 0 on success, 1 on error
948 main (int argc, char *argv[])
953 "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
955 fprintf (stderr, "Usage: interface-name\n" "\n");
958 return hardwaremode (argc, argv);
962 * Copyright (c) 2008, Thomas d'Otreppe
966 * This program is free software; you can redistribute it and/or modify
967 * it under the terms of the GNU General Public License as published by
968 * the Free Software Foundation; either version 2 of the License, or
969 * (at your option) any later version.
971 * This program is distributed in the hope that it will be useful,
972 * but WITHOUT ANY WARRANTY; without even the implied warranty of
973 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
974 * GNU General Public License for more details.
976 * You should have received a copy of the GNU General Public License
977 * along with this program; if not, write to the Free Software
978 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
982 * Return the frequency in Mhz from a channel number
983 * @param channel number of the channel
984 * @return frequency of the channel
987 getFrequencyFromChannel (int channel)
989 static int frequencies[] = {
991 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467,
993 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Nothing from channel 15 to 34 (exclusive)
994 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225,
995 5230, 5235, 5240, 5245,
996 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305,
997 5310, 5315, 5320, 5325,
998 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385,
999 5390, 5395, 5400, 5405,
1000 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465,
1001 5470, 5475, 5480, 5485,
1002 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545,
1003 5550, 5555, 5560, 5565,
1004 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625,
1005 5630, 5635, 5640, 5645,
1006 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705,
1007 5710, 5715, 5720, 5725,
1008 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785,
1009 5790, 5795, 5800, 5805,
1010 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865,
1011 5870, 5875, 5880, 5885,
1012 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945,
1013 5950, 5955, 5960, 5965,
1014 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025,
1015 6030, 6035, 6040, 6045,
1016 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100
1019 return ((channel > 0) &&
1021 sizeof (frequencies) / sizeof (int))) ? frequencies[channel] : -1;
1025 * Return the channel from the frequency (in Mhz)
1026 * @param frequency of the channel
1027 * @return number of the channel
1030 getChannelFromFrequency (int frequency)
1032 if (frequency >= 2412 && frequency <= 2472)
1033 return (frequency - 2407) / 5;
1034 else if (frequency == 2484)
1036 else if (frequency >= 5000 && frequency <= 6100)
1037 return (frequency - 5000) / 5;