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 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
39 #include <netpacket/packet.h>
40 #include <linux/if_ether.h>
42 #include <linux/wireless.h>
43 #include <netinet/in.h>
44 #include <linux/if_tun.h>
52 //#include <sys/utsname.h>
53 #include <sys/param.h>
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"
72 #include "wlan/radiotap-parser.h"
73 /* radiotap-parser defines types like u8 that
74 * ieee80211_radiotap.h needs
76 * we use our local copy of ieee80211_radiotap.h
78 * - since we can't support extensions we don't understand
79 * - since linux does not include it in userspace headers
81 #include "wlan/ieee80211_radiotap.h"
82 #include "wlan/crctable_osdep.h"
83 //#include "wlan/loopback_helper.h"
84 //#include "wlan/ieee80211.h"
85 #include "wlan/helper_common.h"
87 #define ARPHRD_IEEE80211 801
88 #define ARPHRD_IEEE80211_PRISM 802
89 #define ARPHRD_IEEE80211_FULL 803
93 #define MAC_ADDR_SIZE 6
95 //Part taken from file ieee80211.h
97 * Copyright (c) 2001 Atsushi Onoe
98 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
99 * All rights reserved.
101 * Redistribution and use in source and binary forms, with or without
102 * modification, are permitted provided that the following conditions
104 * 1. Redistributions of source code must retain the above copyright
105 * notice, this list of conditions and the following disclaimer.
106 * 2. Redistributions in binary form must reproduce the above copyright
107 * notice, this list of conditions and the following disclaimer in the
108 * documentation and/or other materials provided with the distribution.
109 * 3. The name of the author may not be used to endorse or promote products
110 * derived from this software without specific prior written permission.
112 * Alternatively, this software may be distributed under the terms of the
113 * GNU General Public License ("GPL") version 2 as published by the Free
114 * Software Foundation.
116 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
117 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
118 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
119 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
120 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
121 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
122 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
123 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
125 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127 * $FreeBSD: src/sys/net80211/ieee80211.h,v 1.12 2006/12/01 18:40:51 imp Exp $
130 #define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
133 * generic definitions for IEEE 802.11 frames
135 struct ieee80211_frame
139 u_int8_t i_addr1[IEEE80211_ADDR_LEN];
140 u_int8_t i_addr2[IEEE80211_ADDR_LEN];
141 u_int8_t i_addr3[IEEE80211_ADDR_LEN];
143 /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
149 struct Hardware_Infos
152 struct sendbuf write_pout;
157 * Name of the interface, not necessarily 0-terminated (!).
159 char iface[IFNAMSIZ];
160 unsigned char pl_mac[MAC_ADDR_SIZE];
163 struct RadioTapheader
165 struct ieee80211_radiotap_header header;
173 getChannelFromFrequency (int frequency);
175 // FIXME: make nice...
177 calc_crc_osdep (unsigned char *buf, int len)
179 unsigned long crc = 0xFFFFFFFF;
181 for (; len > 0; len--, buf++)
182 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
187 /* CRC checksum verification routine */
189 // FIXME: make nice...
192 check_crc_buf_osdep (unsigned char *buf, int len)
199 crc = calc_crc_osdep (buf, len);
201 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
202 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
206 // FIXME: make nice...
209 linux_get_channel (struct Hardware_Infos *dev)
215 memset (&wrq, 0, sizeof (struct iwreq));
217 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
220 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
223 frequency = wrq.u.freq.m;
224 if (100000000 < frequency)
226 else if (1000000 < frequency)
229 if (1000 < frequency)
230 chan = getChannelFromFrequency (frequency);
238 // FIXME: make nice...
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);
425 * @return 0 on success
428 openraw (struct Hardware_Infos *dev)
432 struct packet_mreq mr;
433 struct sockaddr_ll sll;
435 /* find the interface index */
436 memset (&ifr, 0, sizeof (ifr));
437 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
438 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
441 "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
442 IFNAMSIZ, dev->iface, strerror (errno));
446 /* lookup the hardware type */
447 memset (&sll, 0, sizeof (sll));
448 sll.sll_family = AF_PACKET;
449 sll.sll_ifindex = ifr.ifr_ifindex;
450 sll.sll_protocol = htons (ETH_P_ALL);
451 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
453 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
454 IFNAMSIZ, dev->iface, strerror (errno));
459 memset (&wrq, 0, sizeof (struct iwreq));
460 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
461 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
463 /* most probably not supported (ie for rtap ipw interface) *
464 * so just assume its correctly set... */
465 wrq.u.mode = IW_MODE_MONITOR;
468 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
469 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
470 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
471 (wrq.u.mode != IW_MODE_MONITOR))
473 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
474 IFNAMSIZ, dev->iface);
478 /* Is interface st to up, broadcast & running ? */
479 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
481 /* Bring interface up */
482 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
484 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
487 "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
488 IFNAMSIZ, dev->iface, strerror (errno));
493 /* bind the raw socket to the interface */
494 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
496 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
497 dev->iface, strerror (errno));
501 /* lookup the hardware type */
502 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
505 "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
506 IFNAMSIZ, dev->iface, strerror (errno));
510 memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
511 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
512 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
513 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
514 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
516 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
517 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
521 /* enable promiscuous mode */
522 memset (&mr, 0, sizeof (mr));
523 mr.mr_ifindex = sll.sll_ifindex;
524 mr.mr_type = PACKET_MR_PROMISC;
526 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
529 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
530 IFNAMSIZ, dev->iface);
538 * @return 0 on success
541 wlaninit (struct Hardware_Infos *dev, const char *iface)
547 dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
550 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
553 if (dev->fd_raw >= FD_SETSIZE)
555 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
556 dev->fd_raw, FD_SETSIZE);
561 /* mac80211 stack detection */
563 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
565 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
567 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
571 strncpy (dev->iface, iface, IFNAMSIZ);
572 if (0 != openraw (dev))
582 * Function to test incoming packets mac for being our own.
584 * @param u8aIeeeHeader buffer of the packet
585 * @param dev the Hardware_Infos struct
586 * @return 0 if mac belongs to us, 1 if mac is for another target
589 mac_test (const struct ieee80211_frame *u8aIeeeHeader,
590 const struct Hardware_Infos *dev)
592 if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
594 if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE))
596 if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
603 * function to set the wlan header to make attacks more difficult
604 * @param u8aIeeeHeader pointer to the header of the packet
605 * @param dev pointer to the Hardware_Infos struct
608 mac_set (struct ieee80211_frame *u8aIeeeHeader,
609 const struct Hardware_Infos *dev)
611 u8aIeeeHeader->i_fc[0] = 0x08;
612 u8aIeeeHeader->i_fc[1] = 0x00;
613 memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
614 memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
620 stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
622 struct Hardware_Infos *dev = cls;
623 struct sendbuf *write_pout = &dev->write_pout;
624 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
625 struct ieee80211_frame *wlanheader;
628 // struct? // FIXME: make nice...
629 struct RadioTapheader rtheader;
631 rtheader.header.it_version = 0;
632 rtheader.header.it_len = htole16 (0x0c);
633 rtheader.header.it_present = htole32 (0x00008004);
634 rtheader.rate = 0x00;
636 htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
638 /* { 0x00, 0x00, <-- radiotap version
639 * 0x0c, 0x00, <- radiotap header length
640 * 0x04, 0x80, 0x00, 0x00, <-- bitmap
642 * 0x00, <-- padding for natural alignment
643 * 0x18, 0x00, <-- TX flags
646 sendsize = ntohs (hdr->size);
648 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
650 fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n");
654 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
656 if (MAXLINE < sendsize)
658 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
661 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
663 fprintf (stderr, "Function stdin_send: wrong packet type\n");
667 rtheader.header.it_len = htole16 (sizeof (rtheader));
668 rtheader.rate = header->rate;
669 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
670 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
671 /* payload contains MAC address, but we don't trust it, so we'll
672 * overwrite it with OUR MAC address again to prevent mischief */
673 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
674 mac_set (wlanheader, dev);
675 write_pout->size = sendsize + sizeof (rtheader);
680 maketest (unsigned char *buf, struct Hardware_Infos *dev)
683 static uint16_t seqenz = 0;
684 static int first = 0;
686 const int rate = 11000000;
687 static const char txt[] =
688 "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
690 unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version
691 0x00, 0x00, // <- radiotap header length
692 0x04, 0x80, 0x02, 0x00, // <-- bitmap
694 0x00, // <-- padding for natural alignment
695 0x10, 0x00, // <-- TX flags
699 /*uint8_t u8aRadiotap[] =
701 * 0x00, 0x00, // <-- radiotap version
702 * 0x19, 0x00, // <- radiotap header length
703 * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
704 * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
705 * 0x00, // <-- flags (Offset +0x10)
706 * 0x6c, // <-- rate (0ffset +0x11)
707 * 0x71, 0x09, 0xc0, 0x00, // <-- channel
708 * 0xde, // <-- antsignal
709 * 0x00, // <-- antnoise
710 * 0x01, // <-- antenna
713 u8aRadiotap[8] = (rate / 500000);
714 u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
716 static struct ieee80211_frame u8aIeeeHeader;
718 uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
719 // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
720 // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
721 0x00, 0x00, // Duration/ID
723 //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
724 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
725 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
726 //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
727 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
728 0x10, 0x86, //Sequence Control
732 memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
733 memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
737 tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
740 htole16 ((sizeof (txt) +
741 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
742 tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
744 (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
745 IEEE80211_SEQ_SEQ_SHIFT);
748 memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
749 memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
750 memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
752 return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
759 * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
760 * @param buffer pointer to buffer for the message
761 * @param mac pointer to the mac address
762 * @return number of bytes written
764 // FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file)
767 send_mac_to_plugin (char *buffer, struct MacAddress * mac)
769 struct Wlan_Helper_Control_Message macmsg;
771 macmsg.hdr.size = htons (sizeof (struct Wlan_Helper_Control_Message));
772 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
773 memcpy (macmsg.mac, mac, sizeof (struct MacAddress));
774 memcpy (buffer, &macmsg, sizeof (struct Wlan_Helper_Control_Message));
775 return sizeof (struct Wlan_Helper_Control_Message);
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 (int argc, char *argv[])
947 "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
949 fprintf (stderr, "Usage: interface-name\n" "\n");
952 return hardwaremode (argc, argv);
956 * Copyright (c) 2008, Thomas d'Otreppe
960 * This program is free software; you can redistribute it and/or modify
961 * it under the terms of the GNU General Public License as published by
962 * the Free Software Foundation; either version 2 of the License, or
963 * (at your option) any later version.
965 * This program is distributed in the hope that it will be useful,
966 * but WITHOUT ANY WARRANTY; without even the implied warranty of
967 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
968 * GNU General Public License for more details.
970 * You should have received a copy of the GNU General Public License
971 * along with this program; if not, write to the Free Software
972 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
976 * Return the frequency in Mhz from a channel number
979 getFrequencyFromChannel (int channel)
981 static int frequencies[] = {
983 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467,
985 -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)
986 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225,
987 5230, 5235, 5240, 5245,
988 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305,
989 5310, 5315, 5320, 5325,
990 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385,
991 5390, 5395, 5400, 5405,
992 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465,
993 5470, 5475, 5480, 5485,
994 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545,
995 5550, 5555, 5560, 5565,
996 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625,
997 5630, 5635, 5640, 5645,
998 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705,
999 5710, 5715, 5720, 5725,
1000 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785,
1001 5790, 5795, 5800, 5805,
1002 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865,
1003 5870, 5875, 5880, 5885,
1004 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945,
1005 5950, 5955, 5960, 5965,
1006 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025,
1007 6030, 6035, 6040, 6045,
1008 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100
1011 return (channel > 0 && channel <= 221) ? frequencies[channel] : -1;
1015 * Return the channel from the frequency (in Mhz)
1018 getChannelFromFrequency (int frequency)
1020 if (frequency >= 2412 && frequency <= 2472)
1021 return (frequency - 2407) / 5;
1022 else if (frequency == 2484)
1024 else if (frequency >= 5000 && frequency <= 6100)
1025 return (frequency - 5000) / 5;