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"
86 #define ARPHRD_IEEE80211 801
87 #define ARPHRD_IEEE80211_PRISM 802
88 #define ARPHRD_IEEE80211_FULL 803
90 #include "wlan/loopback_helper.h"
94 #define MAC_ADDR_SIZE 6
99 struct sendbuf write_pout;
104 * Name of the interface, not necessarily 0-terminated (!).
106 char iface[IFNAMSIZ];
107 unsigned char pl_mac[MAC_ADDR_SIZE];
112 getChannelFromFrequency (int frequency);
114 // FIXME: make nice...
116 calc_crc_osdep (unsigned char *buf, int len)
118 unsigned long crc = 0xFFFFFFFF;
120 for (; len > 0; len--, buf++)
121 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
126 /* CRC checksum verification routine */
128 // FIXME: make nice...
130 check_crc_buf_osdep (unsigned char *buf, int len)
137 crc = calc_crc_osdep (buf, len);
139 return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
140 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]);
144 // FIXME: make nice...
146 linux_get_channel (struct Hardware_Infos *dev)
152 memset (&wrq, 0, sizeof (struct iwreq));
154 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
157 if (0 > ioctl (fd, SIOCGIWFREQ, &wrq))
160 frequency = wrq.u.freq.m;
161 if (100000000 < frequency)
163 else if (1000000 < frequency)
166 if (1000 < frequency)
167 chan = getChannelFromFrequency (frequency);
175 // FIXME: make nice...
177 linux_read (struct Hardware_Infos *dev, unsigned char *buf, /* FIXME: void*? */
178 size_t buf_size, struct Radiotap_rx *ri)
180 unsigned char tmpbuf[buf_size];
182 int n, got_signal, got_noise, got_channel, fcs_removed;
184 n = got_signal = got_noise = got_channel = fcs_removed = 0;
186 caplen = read (dev->fd_raw, tmpbuf, buf_size);
191 fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
195 memset (buf, 0, buf_size);
196 memset (ri, 0, sizeof (*ri));
198 switch (dev->arptype_in)
200 case ARPHRD_IEEE80211_PRISM:
202 /* skip the prism header */
203 if (tmpbuf[7] == 0x40)
205 /* prism54 uses a different format */
206 ri->ri_power = tmpbuf[0x33];
207 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12);
208 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000;
215 ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48);
216 ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36);
217 ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C);
218 ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12);
219 ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000;
223 n = *(int *) (tmpbuf + 4);
226 if (n < 8 || n >= caplen)
231 case ARPHRD_IEEE80211_FULL:
233 struct ieee80211_radiotap_iterator iterator;
234 struct ieee80211_radiotap_header *rthdr;
236 rthdr = (struct ieee80211_radiotap_header *) tmpbuf;
238 if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0)
241 /* go through the radiotap arguments we have been given
245 while (ieee80211_radiotap_iterator_next (&iterator) >= 0)
248 switch (iterator.this_arg_index)
251 case IEEE80211_RADIOTAP_TSFT:
252 ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg));
255 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
258 if (*iterator.this_arg < 127)
259 ri->ri_power = *iterator.this_arg;
261 ri->ri_power = *iterator.this_arg - 255;
267 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
270 if (*iterator.this_arg < 127)
271 ri->ri_power = *iterator.this_arg;
273 ri->ri_power = *iterator.this_arg - 255;
279 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
282 if (*iterator.this_arg < 127)
283 ri->ri_noise = *iterator.this_arg;
285 ri->ri_noise = *iterator.this_arg - 255;
291 case IEEE80211_RADIOTAP_DB_ANTNOISE:
294 if (*iterator.this_arg < 127)
295 ri->ri_noise = *iterator.this_arg;
297 ri->ri_noise = *iterator.this_arg - 255;
303 case IEEE80211_RADIOTAP_ANTENNA:
304 ri->ri_antenna = *iterator.this_arg;
307 case IEEE80211_RADIOTAP_CHANNEL:
308 ri->ri_channel = *iterator.this_arg;
312 case IEEE80211_RADIOTAP_RATE:
313 ri->ri_rate = (*iterator.this_arg) * 500000;
316 case IEEE80211_RADIOTAP_FLAGS:
317 /* is the CRC visible at the end?
320 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS)
326 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS)
332 n = le16_to_cpu (rthdr->it_len);
333 if (n <= 0 || n >= caplen)
337 case ARPHRD_IEEE80211:
347 //detect fcs at the end, even if the flag wasn't set and remove it
348 if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4)))
352 memcpy (buf, tmpbuf + n, caplen);
354 ri->ri_channel = linux_get_channel (dev);
361 * @return 0 on success
364 openraw (struct Hardware_Infos *dev)
368 struct packet_mreq mr;
369 struct sockaddr_ll sll;
371 /* find the interface index */
372 memset (&ifr, 0, sizeof (ifr));
373 strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
374 if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
377 "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
378 IFNAMSIZ, dev->iface, strerror (errno));
382 /* lookup the hardware type */
383 memset (&sll, 0, sizeof (sll));
384 sll.sll_family = AF_PACKET;
385 sll.sll_ifindex = ifr.ifr_ifindex;
386 sll.sll_protocol = htons (ETH_P_ALL);
387 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
389 fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
390 IFNAMSIZ, dev->iface, strerror (errno));
395 memset (&wrq, 0, sizeof (struct iwreq));
396 strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
397 if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
399 /* most probably not supported (ie for rtap ipw interface) *
400 * so just assume its correctly set... */
401 wrq.u.mode = IW_MODE_MONITOR;
404 if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
405 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
406 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) ||
407 (wrq.u.mode != IW_MODE_MONITOR))
409 fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
410 IFNAMSIZ, dev->iface);
414 /* Is interface st to up, broadcast & running ? */
415 if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
417 /* Bring interface up */
418 ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
420 if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
423 "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
424 IFNAMSIZ, dev->iface, strerror (errno));
429 /* bind the raw socket to the interface */
430 if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
432 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
433 dev->iface, strerror (errno));
437 /* lookup the hardware type */
438 if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
441 "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
442 IFNAMSIZ, dev->iface, strerror (errno));
446 memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
447 dev->arptype_in = ifr.ifr_hwaddr.sa_family;
448 if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
449 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
450 (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
452 fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
453 ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
457 /* enable promiscuous mode */
458 memset (&mr, 0, sizeof (mr));
459 mr.mr_ifindex = sll.sll_ifindex;
460 mr.mr_type = PACKET_MR_PROMISC;
462 setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
465 fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n",
466 IFNAMSIZ, dev->iface);
474 * @return 0 on success
477 wlaninit (struct Hardware_Infos *dev, const char *iface)
483 dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
486 fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno));
489 if (dev->fd_raw >= FD_SETSIZE)
491 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
492 dev->fd_raw, FD_SETSIZE);
497 /* mac80211 stack detection */
499 snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem",
501 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
503 fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface);
507 strncpy (dev->iface, iface, IFNAMSIZ);
508 if (0 != openraw (dev))
518 * Function to test incoming packets mac for being our own.
520 * @param u8aIeeeHeader buffer of the packet
521 * @param dev the Hardware_Infos struct
522 * @return 0 if mac belongs to us, 1 if mac is for another target
525 mac_test (const struct ieee80211_frame *u8aIeeeHeader,
526 const struct Hardware_Infos *dev)
528 if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE))
530 if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE))
532 if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE))
539 * function to set the wlan header to make attacks more difficult
540 * @param buf buffer of the packet
541 * @param dev pointer to the Hardware_Infos struct
544 mac_set (struct ieee80211_frame *u8aIeeeHeader,
545 const struct Hardware_Infos *dev)
547 u8aIeeeHeader->i_fc[0] = 0x08;
548 u8aIeeeHeader->i_fc[1] = 0x00;
549 memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
550 memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE);
554 struct RadioTapheader
556 struct ieee80211_radiotap_header header;
563 stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
565 struct Hardware_Infos *dev = cls;
566 struct sendbuf *write_pout = &dev->write_pout;
567 struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1];
568 struct ieee80211_frame *wlanheader;
571 // struct? // FIXME: make nice...
572 struct RadioTapheader rtheader;
574 rtheader.header.it_version = 0;
575 rtheader.header.it_len = htole16 (0x0c);
576 rtheader.header.it_present = htole32 (0x00008004);
577 rtheader.rate = 0x00;
579 htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
581 /* { 0x00, 0x00, <-- radiotap version
582 * 0x0c, 0x00, <- radiotap header length
583 * 0x04, 0x80, 0x00, 0x00, <-- bitmap
585 * 0x00, <-- padding for natural alignment
586 * 0x18, 0x00, <-- TX flags
589 sendsize = ntohs (hdr->size);
591 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader))
593 fprintf (stderr, "Function stdin_send_hw: mailformed packet (too small)\n");
597 sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader);
599 if (MAXLINE < sendsize)
601 fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n");
604 if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type))
606 fprintf (stderr, "Function stdin_send: wrong packet type\n");
610 rtheader.header.it_len = htole16 (sizeof (rtheader));
611 rtheader.rate = header->rate;
612 memcpy (write_pout->buf, &rtheader, sizeof (rtheader));
613 memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize);
614 /* payload contains MAC address, but we don't trust it, so we'll
615 * overwrite it with OUR MAC address again to prevent mischief */
616 wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader));
617 mac_set (wlanheader, dev);
618 write_pout->size = sendsize + sizeof (rtheader);
623 maketest (unsigned char *buf, struct Hardware_Infos *dev)
626 static uint16_t seqenz = 0;
627 static int first = 0;
629 const int rate = 11000000;
630 static const char txt[] =
631 "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211";
633 unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version
634 0x00, 0x00, // <- radiotap header length
635 0x04, 0x80, 0x02, 0x00, // <-- bitmap
637 0x00, // <-- padding for natural alignment
638 0x10, 0x00, // <-- TX flags
642 /*uint8_t u8aRadiotap[] =
644 * 0x00, 0x00, // <-- radiotap version
645 * 0x19, 0x00, // <- radiotap header length
646 * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
647 * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
648 * 0x00, // <-- flags (Offset +0x10)
649 * 0x6c, // <-- rate (0ffset +0x11)
650 * 0x71, 0x09, 0xc0, 0x00, // <-- channel
651 * 0xde, // <-- antsignal
652 * 0x00, // <-- antnoise
653 * 0x01, // <-- antenna
656 u8aRadiotap[8] = (rate / 500000);
657 u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap));
659 static struct ieee80211_frame u8aIeeeHeader;
661 uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0;
662 // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data
663 // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS;
664 0x00, 0x00, // Duration/ID
666 //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver
667 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver
668 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender
669 //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4,
670 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid
671 0x10, 0x86, //Sequence Control
675 memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame));
676 memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE);
680 tmp16 = (uint16_t *) u8aIeeeHeader.i_dur;
683 htole16 ((sizeof (txt) +
684 sizeof (struct ieee80211_frame) * 1000000) / rate + 290);
685 tmp16 = (uint16_t *) u8aIeeeHeader.i_seq;
687 (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) <<
688 IEEE80211_SEQ_SEQ_SHIFT);
691 memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap));
692 memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader));
693 memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt,
695 return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt);
702 * function to create GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL message for plugin
703 * @param buffer pointer to buffer for the message
704 * @param mac pointer to the mac address
705 * @return number of bytes written
707 // FIXME: use 'struct MacAddress' for 'mac' (everywhere in this file)
709 send_mac_to_plugin (char *buffer, uint8_t * mac)
711 struct Wlan_Helper_Control_Message macmsg;
713 macmsg.hdr.size = htons (sizeof (struct Wlan_Helper_Control_Message));
714 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
715 memcpy (macmsg.mac.mac, mac, sizeof (struct MacAddress));
716 memcpy (buffer, &macmsg, sizeof (struct Wlan_Helper_Control_Message));
717 return sizeof (struct Wlan_Helper_Control_Message);
722 hardwaremode (int argc, char *argv[])
725 struct Hardware_Infos dev;
726 char readbuf[MAXLINE];
727 struct sendbuf write_std;
734 struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
736 if (0 != wlaninit (&dev, argv[1]))
739 if (0 != setresuid (uid, uid, uid))
741 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
742 /* not critical, continue anyway */
745 dev.write_pout.size = 0;
746 dev.write_pout.pos = 0;
747 stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev);
749 /* send mac to STDOUT first */
751 write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac);
758 if ((0 == dev.write_pout.size) && (1 == stdin_open))
760 FD_SET (STDIN_FILENO, &rfds);
761 maxfd = MAX (maxfd, STDIN_FILENO);
763 if (0 == write_std.size)
765 FD_SET (dev.fd_raw, &rfds);
766 maxfd = MAX (maxfd, dev.fd_raw);
769 if (0 < write_std.size)
771 FD_SET (STDOUT_FILENO, &wfds);
772 maxfd = MAX (maxfd, STDOUT_FILENO);
774 if (0 < dev.write_pout.size)
776 FD_SET (dev.fd_raw, &wfds);
777 maxfd = MAX (maxfd, dev.fd_raw);
779 retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
780 if ((-1 == retval) && (EINTR == errno))
784 fprintf (stderr, "select failed: %s\n", strerror (errno));
788 if (FD_ISSET (STDOUT_FILENO, &wfds))
791 write (STDOUT_FILENO, write_std.buf + write_std.pos,
792 write_std.size - write_std.pos);
795 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
798 write_std.pos += ret;
799 if (write_std.pos == write_std.size)
806 if (FD_ISSET (dev.fd_raw, &wfds))
808 ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size);
812 "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n",
813 __LINE__, strerror (errno), dev.write_pout.size);
816 dev.write_pout.pos += ret;
817 if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0))
819 fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n",
820 __LINE__, dev.write_pout.pos, dev.write_pout.size);
823 if (dev.write_pout.pos == dev.write_pout.size)
825 dev.write_pout.pos = 0;
826 dev.write_pout.size = 0;
830 if (FD_ISSET (STDIN_FILENO, &rfds))
832 ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
835 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
840 /* stop reading... */
843 GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO,
847 if (FD_ISSET (dev.fd_raw, &rfds))
849 struct GNUNET_MessageHeader *header;
850 struct Radiotap_rx *rxinfo;
851 struct ieee80211_frame *datastart;
853 header = (struct GNUNET_MessageHeader *) write_std.buf;
854 rxinfo = (struct Radiotap_rx *) &header[1];
855 datastart = (struct ieee80211_frame *) &rxinfo[1];
857 linux_read (&dev, (unsigned char *) datastart,
858 sizeof (write_std.buf) - sizeof (struct Radiotap_rx) -
859 sizeof (struct GNUNET_MessageHeader), rxinfo);
862 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
865 if ((0 < ret) && (0 == mac_test (datastart, &dev)))
868 ret + sizeof (struct GNUNET_MessageHeader) +
869 sizeof (struct Radiotap_rx);
870 header->size = htons (write_std.size);
871 header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
876 /* Error handling, try to clean up a bit at least */
877 GNUNET_SERVER_mst_destroy (stdin_mst);
883 main (int argc, char *argv[])
888 "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n",
890 fprintf (stderr, "Usage: interface-name\n" "\n");
893 return hardwaremode (argc, argv);