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;
645 htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
647 /* { 0x00, 0x00, <-- radiotap version
648 * 0x0c, 0x00, <- radiotap header length
649 * 0x04, 0x80, 0x00, 0x00, <-- bitmap
651 * 0x00, <-- padding for natural alignment
652 * 0x18, 0x00, <-- TX flags
655 sendsize = ntohs (hdr->size);
657 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
659 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
663 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
665 if (MAXLINE < sendsize)
667 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
670 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
672 fprintf (stderr, "Function stdin_send: wrong packet type\n");
676 rtheader.header.it_len = htole16 (sizeof (rtheader));
677 rtheader.rate = header->rate;
678 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
679 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
680 /* payload contains MAC address, but we don't trust it, so we'll
681 * overwrite it with OUR MAC address again to prevent mischief */
682 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
683 mac_set (wlanheader, dev);
684 write_pout->size = sendsize + sizeof (rtheader);
689 * Function to make test packets with special options
690 * @param buf buffer to write the data to
691 * @param dev device to send the data from
692 * @return size of packet (what should be send)
695 maketest (unsigned char *buf, struct Hardware_Infos *dev)
698 static uint16_t seqenz = 0;
699 static int first = 0;
701 const int rate = 11000000;
702 static const char txt[] =
703 "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
705 unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version
706 0x00, 0x00, // <- radiotap header length
707 0x04, 0x80, 0x02, 0x00, // <-- bitmap
709 0x00, // <-- padding for natural alignment
710 0x10, 0x00, // <-- TX flags
714 /*uint8_t u8aRadiotap[] =
716 * 0x00, 0x00, // <-- radiotap version
717 * 0x19, 0x00, // <- radiotap header length
718 * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
719 * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
720 * 0x00, // <-- flags (Offset +0x10)
721 * 0x6c, // <-- rate (0ffset +0x11)
722 * 0x71, 0x09, 0xc0, 0x00, // <-- channel
723 * 0xde, // <-- antsignal
724 * 0x00, // <-- antnoise
725 * 0x01, // <-- antenna
728 u8aRadiotap[8] = (rate / 500000);
729 u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
731 static struct ieee80211_frame u8aIeeeHeader;
733 uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
734 // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
735 // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
736 0x00, 0x00, // Duration/ID
738 //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
739 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
740 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
741 //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
742 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
743 0x10, 0x86, //Sequence Control
747 memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
748 memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
752 tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
755 htole16 ((sizeof (txt) +
756 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
757 tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
759 (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
760 IEEE80211_SEQ_SEQ_SHIFT);
763 memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
764 memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
765 memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
767 return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
774 * Function to start the hardware for the wlan helper
775 * @param argc number of arguments
776 * @param argv arguments
777 * @return returns one on error
780 hardwaremode (int argc, char *argv[])
783 struct Hardware_Infos dev;
784 char readbuf[MAXLINE];
785 struct sendbuf write_std;
792 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
794 if (0 != wlaninit (&dev, argv[1]))
797 if (0 != setresuid (uid, uid, uid))
799 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
800 /* not critical, continue anyway */
803 dev.write_pout.size = 0;
804 dev.write_pout.pos = 0;
805 stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
807 /* send mac to STDOUT first */
809 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac);
816 if ((0 == dev.write_pout.size) && (1 == stdin_open))
818 FD_SET (STDIN_FILENO, &rfds);
819 maxfd = MAX (maxfd, STDIN_FILENO);
821 if (0 == write_std.size)
823 FD_SET (dev.fd_raw, &rfds);
824 maxfd = MAX (maxfd, dev.fd_raw);
827 if (0 < write_std.size)
829 FD_SET (STDOUT_FILENO, &wfds);
830 maxfd = MAX (maxfd, STDOUT_FILENO);
832 if (0 < dev.write_pout.size)
834 FD_SET (dev.fd_raw, &wfds);
835 maxfd = MAX (maxfd, dev.fd_raw);
837 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
838 if ((-1 == retval) && (EINTR == errno))
842 fprintf (stderr, "select failed: %s\n", strerror (errno));
846 if (FD_ISSET (STDOUT_FILENO, &wfds))
849 write (STDOUT_FILENO, write_std.buf + write_std.pos,
850 write_std.size - write_std.pos);
853 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
856 write_std.pos += ret;
857 if (write_std.pos == write_std.size)
864 if (FD_ISSET (dev.fd_raw, &wfds))
866 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
870 "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n",
871 __LINE__, strerror (errno), dev.write_pout.size);
874 dev.write_pout.pos += ret;
875 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
877 fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n",
878 __LINE__, dev.write_pout.pos, dev.write_pout.size);
881 if (dev.write_pout.pos == dev.write_pout.size)
883 dev.write_pout.pos = 0;
884 dev.write_pout.size = 0;
888 if (FD_ISSET (STDIN_FILENO, &rfds))
890 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
893 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
898 /* stop reading... */
901 GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
905 if (FD_ISSET (dev.fd_raw, &rfds))
907 struct GNUNET_MessageHeader *header;
908 struct Radiotap_rx *rxinfo;
909 struct ieee80211_frame *datastart;
911 header = (struct GNUNET_MessageHeader *) write_std.buf;
912 rxinfo = (struct Radiotap_rx *) &header[1];
913 datastart = (struct ieee80211_frame *) &rxinfo[1];
915 linux_read (&dev, (unsigned char *) datastart,
916 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
917 sizeof (struct GNUNET_MessageHeader), rxinfo);
920 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
923 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
926 ret + sizeof (struct GNUNET_MessageHeader) +
927 sizeof (struct Radiotap_rx);
928 header->size = htons (write_std.size);
929 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
934 /* Error handling, try to clean up a bit at least */
935 GNUNET_SERVER_mst_destroy (stdin_mst);
941 * main function of the helper
942 * @param argc number of arguments
943 * @param argv arguments
944 * @return 0 on success, 1 on error
947 main (int argc, char *argv[])
952 "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
954 fprintf (stderr, "Usage: interface-name\n" "\n");
957 return hardwaremode (argc, argv);
961 * Copyright (c) 2008, Thomas d'Otreppe
965 * This program is free software; you can redistribute it and/or modify
966 * it under the terms of the GNU General Public License as published by
967 * the Free Software Foundation; either version 2 of the License, or
968 * (at your option) any later version.
970 * This program is distributed in the hope that it will be useful,
971 * but WITHOUT ANY WARRANTY; without even the implied warranty of
972 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
973 * GNU General Public License for more details.
975 * You should have received a copy of the GNU General Public License
976 * along with this program; if not, write to the Free Software
977 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
981 * Return the frequency in Mhz from a channel number
982 * @param channel number of the channel
983 * @return frequency of the channel
986 getFrequencyFromChannel (int channel)
988 static int frequencies[] = {
990 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467,
992 -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)
993 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225,
994 5230, 5235, 5240, 5245,
995 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305,
996 5310, 5315, 5320, 5325,
997 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385,
998 5390, 5395, 5400, 5405,
999 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465,
1000 5470, 5475, 5480, 5485,
1001 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545,
1002 5550, 5555, 5560, 5565,
1003 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625,
1004 5630, 5635, 5640, 5645,
1005 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705,
1006 5710, 5715, 5720, 5725,
1007 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785,
1008 5790, 5795, 5800, 5805,
1009 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865,
1010 5870, 5875, 5880, 5885,
1011 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945,
1012 5950, 5955, 5960, 5965,
1013 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025,
1014 6030, 6035, 6040, 6045,
1015 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100
1018 return (channel > 0 && channel <= 221) ? frequencies[channel] : -1;
1022 * Return the channel from the frequency (in Mhz)
1023 * @param frequency of the channel
1024 * @return number of the channel
1027 getChannelFromFrequency (int frequency)
1029 if (frequency >= 2412 && frequency <= 2472)
1030 return (frequency - 2407) / 5;
1031 else if (frequency == 2484)
1033 else if (frequency >= 5000 && frequency <= 6100)
1034 return (frequency - 5000) / 5;