X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-transport-wlan-helper.c;h=25e55e510a583ca3287aa457608a10addb84f999;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=633b2776c9ed3e083683bd3235207f26960ad0c4;hpb=d0d88da8754bd5184be826dc4d271c5abeece0c5;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 633b2776c..25e55e510 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 2011 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -28,6 +28,11 @@ * gnunet */ +/** + * parts taken from aircrack-ng, parts changend. + */ + +#define _GNU_SOURCE #include #include #include @@ -45,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -56,7 +60,6 @@ //#include #include #include - //#include #include */ //#include "platform.h" @@ -70,11 +73,6 @@ #include "gnunet-transport-wlan-helper.h" #include "gnunet_crypto_lib.h" -#include -#include -#include -#include - #include "wlan/radiotap-parser.h" /* radiotap-parser defines types like u8 that * ieee80211_radiotap.h needs @@ -86,87 +84,81 @@ */ #include "wlan/ieee80211_radiotap.h" #include "wlan/crctable_osdep.h" -#include "wlan/loopback_helper.h" -#include "wlan/ieee80211.h" +//#include "wlan/loopback_helper.h" +//#include "wlan/ieee80211.h" +#include "wlan/helper_common.h" #define ARPHRD_IEEE80211 801 #define ARPHRD_IEEE80211_PRISM 802 #define ARPHRD_IEEE80211_FULL 803 -int closeprog; +#define DEBUG 1 + +#define MAC_ADDR_SIZE 6 -#include "wlan/helper_common.h" -#include "wlan/loopback_helper.h" -#define DEBUG 1 +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ -typedef enum +/* + * generic definitions for IEEE 802.11 frames + */ +struct ieee80211_frame { - DT_NULL = 0, - DT_WLANNG, - DT_HOSTAP, - DT_MADWIFI, - DT_MADWIFING, - DT_BCM43XX, - DT_ORINOCO, - DT_ZD1211RW, - DT_ACX, - DT_MAC80211_RT, - DT_AT76USB, - DT_IPW2200 - -} DRIVER_TYPE; - -static const char * szaDriverTypes[] = - { [DT_NULL] = "Unknown", [DT_WLANNG] = "Wlan-NG", [DT_HOSTAP] = "HostAP", - [DT_MADWIFI] = "Madwifi", [DT_MADWIFING] = "Madwifi-NG", - [DT_BCM43XX] = "BCM43xx", [DT_ORINOCO] = "Orinoco", - [DT_ZD1211RW] = "ZD1211RW", [DT_ACX] = "ACX", - [DT_MAC80211_RT] = "Mac80211-Radiotap", [DT_AT76USB] = "Atmel 76_usb", - [DT_IPW2200] = "ipw2200" }; + u_int8_t i_fc[2]; + u_int8_t i_dur[2]; + u_int8_t i_addr1[IEEE80211_ADDR_LEN]; + u_int8_t i_addr2[IEEE80211_ADDR_LEN]; + u_int8_t i_addr3[IEEE80211_ADDR_LEN]; + u_int8_t i_seq[2]; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} GNUNET_PACKED; +/** + * struct for storing the information of the hardware + */ struct Hardware_Infos { - struct sendbuf *write_pout; - int fd_in, arptype_in; - int fd_out; + /** + * send buffer + */ + struct sendbuf write_pout; + /** + * file descriptor for the raw socket + */ + int fd_raw; - DRIVER_TYPE drivertype; /* inited to DT_UNKNOWN on allocation by wi_alloc */ + int arptype_in; - char *iface; - unsigned char pl_mac[6]; + /** + * Name of the interface, not necessarily 0-terminated (!). + */ + char iface[IFNAMSIZ]; + unsigned char pl_mac[MAC_ADDR_SIZE]; }; - -/* wifi bitrate to use in 500kHz units */ - -/* - static const u8 u8aRatesToUse[] = - { - - 54 * 2, 48 * 2, 36 * 2, 24 * 2, 18 * 2, 12 * 2, 9 * 2, 11 * 2, 11, // 5.5 - 2 * 2, 1 * 2 }; - -*/ -static void -sigfunc_hw(int sig) +struct RadioTapheader { - closeprog = 1; -} + struct ieee80211_radiotap_header header; + u8 rate; + u8 pad1; + u16 txflags; +}; -static void -usage() -{ - printf("Usage: interface-name options\n" - "options: 0 = with hardware\n" - "1 = first loopback file\n" - "2 = second loopback file\n" - "\n"); -} +// FIXME: inline? +int +getChannelFromFrequency (int frequency); +// FIXME: make nice... +/** + * function to calculate the crc, the start of the calculation + * @param buf buffer to calc the crc + * @param len len of the buffer + * @return crc sum + */ static unsigned long -calc_crc_osdep(unsigned char * buf, int len) +calc_crc_osdep (unsigned char *buf, int len) { unsigned long crc = 0xFFFFFFFF; @@ -178,291 +170,263 @@ calc_crc_osdep(unsigned char * buf, int len) /* CRC checksum verification routine */ +// FIXME: make nice... +/** + * Function to check crc of the wlan packet + * @param buf buffer of the packet + * @param len len of the data + * @return crc sum of the data + */ static int -check_crc_buf_osdep(unsigned char *buf, int len) +check_crc_buf_osdep (unsigned char *buf, int len) { unsigned long crc; if (0 > len) return 0; - crc = calc_crc_osdep(buf, len); + crc = calc_crc_osdep (buf, len); buf += len; - return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && ((crc - >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); + return (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] && + ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3]); } + +// FIXME: make nice... +/** + * function to get the channel of a specific wlan card + * @param dev pointer to the dev struct of the card + * @return channel number + */ static int -linux_get_channel(struct Hardware_Infos *dev) +linux_get_channel (struct Hardware_Infos *dev) { struct iwreq wrq; int fd, frequency; int chan = 0; - memset(&wrq, 0, sizeof(struct iwreq)); + memset (&wrq, 0, sizeof (struct iwreq)); - strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ ); + strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); - fd = dev->fd_in; - if (0 > ioctl(fd, SIOCGIWFREQ, &wrq)) + fd = dev->fd_raw; + if (0 > ioctl (fd, SIOCGIWFREQ, &wrq)) return (-1); frequency = wrq.u.freq.m; - if (100000000 < frequency ) + if (100000000 < frequency) frequency /= 100000; - else if (1000000 < frequency ) + else if (1000000 < frequency) frequency /= 1000; if (1000 < frequency) - chan = getChannelFromFrequency(frequency); + chan = getChannelFromFrequency (frequency); else chan = frequency; return chan; } -static int -linux_read(struct Hardware_Infos * dev, unsigned char *buf, int count, - struct Radiotap_rx * ri) -{ - unsigned char tmpbuf[4096 * 4]; - int caplen, n, got_signal, got_noise, got_channel, fcs_removed; +// FIXME: make nice... +/** + * function to read from a wlan card + * @param dev pointer to the struct of the wlan card + * @param buf buffer to read to + * @param buf_size size of the buffer + * @param ri radiotap_rx info + * @return size read from the buffer + */ +static ssize_t +linux_read (struct Hardware_Infos *dev, unsigned char *buf, /* FIXME: void*? */ + size_t buf_size, struct Radiotap_rx *ri) +{ + unsigned char tmpbuf[buf_size]; + ssize_t caplen; + int n, got_signal, got_noise, got_channel, fcs_removed; - caplen = n = got_signal = got_noise = got_channel = fcs_removed = 0; + n = got_signal = got_noise = got_channel = fcs_removed = 0; - if ((unsigned) count > sizeof(tmpbuf)) - return (-1); - caplen = read(dev->fd_in, tmpbuf, count); + caplen = read (dev->fd_raw, tmpbuf, buf_size); if (0 > caplen) + { + if (EAGAIN == errno) + return 0; + fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno)); + return -1; + } + + memset (buf, 0, buf_size); + memset (ri, 0, sizeof (*ri)); + + switch (dev->arptype_in) + { + case ARPHRD_IEEE80211_PRISM: + { + /* skip the prism header */ + if (tmpbuf[7] == 0x40) { - if (EAGAIN == errno) - return (0); - - perror("read failed"); - return (-1); + /* prism54 uses a different format */ + ri->ri_power = tmpbuf[0x33]; + ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); + ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; + got_signal = 1; + got_noise = 1; + n = 0x40; } - - memset(buf, 0, sizeof(buf)); - - if (ri) - memset(ri, 0, sizeof(*ri)); - - if (ARPHRD_IEEE80211_PRISM == dev->arptype_in ) + else { - /* skip the prism header */ - if (tmpbuf[7] == 0x40) - { - /* prism54 uses a different format */ - if (ri) - { - ri->ri_power = tmpbuf[0x33]; - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x33 + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x33 + 24)) * 500000; - - got_signal = 1; - got_noise = 1; - } - - n = 0x40; - } - else - { - if (ri) - { - ri->ri_mactime = *(u_int64_t*) (tmpbuf + 0x5C - 48); - ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); - ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); - ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); - ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; - - got_channel = 1; - got_signal = 1; - got_noise = 1; - } - - n = *(int *) (tmpbuf + 4); - } - - if (n < 8 || n >= caplen) - return (0); + ri->ri_mactime = *(u_int64_t *) (tmpbuf + 0x5C - 48); + ri->ri_channel = *(unsigned int *) (tmpbuf + 0x5C - 36); + ri->ri_power = *(unsigned int *) (tmpbuf + 0x5C); + ri->ri_noise = *(unsigned int *) (tmpbuf + 0x5C + 12); + ri->ri_rate = (*(unsigned int *) (tmpbuf + 0x5C + 24)) * 500000; + got_channel = 1; + got_signal = 1; + got_noise = 1; + n = *(int *) (tmpbuf + 4); } - if (ARPHRD_IEEE80211_FULL == dev->arptype_in) - { - struct ieee80211_radiotap_iterator iterator; - struct ieee80211_radiotap_header *rthdr; + if (n < 8 || n >= caplen) + return (0); + } + break; - rthdr = (struct ieee80211_radiotap_header *) tmpbuf; + case ARPHRD_IEEE80211_FULL: + { + struct ieee80211_radiotap_iterator iterator; + struct ieee80211_radiotap_header *rthdr; - if (ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen) < 0) - return (0); + rthdr = (struct ieee80211_radiotap_header *) tmpbuf; - /* go through the radiotap arguments we have been given - * by the driver - */ + if (ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen) < 0) + return (0); - while (ri && (ieee80211_radiotap_iterator_next(&iterator) >= 0)) - { - - switch (iterator.this_arg_index) - { - - case IEEE80211_RADIOTAP_TSFT: - ri->ri_mactime = le64_to_cpu(*((uint64_t*) iterator.this_arg)); - break; - - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - if (!got_signal) - { - if (*iterator.this_arg < 127) - ri->ri_power = *iterator.this_arg; - else - ri->ri_power = *iterator.this_arg - 255; - - got_signal = 1; - } - break; - - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_DB_ANTNOISE: - if (!got_noise) - { - if (*iterator.this_arg < 127) - ri->ri_noise = *iterator.this_arg; - else - ri->ri_noise = *iterator.this_arg - 255; - - got_noise = 1; - } - break; - - case IEEE80211_RADIOTAP_ANTENNA: - ri->ri_antenna = *iterator.this_arg; - break; - - case IEEE80211_RADIOTAP_CHANNEL: - ri->ri_channel = *iterator.this_arg; - got_channel = 1; - break; - - case IEEE80211_RADIOTAP_RATE: - ri->ri_rate = (*iterator.this_arg) * 500000; - break; - - case IEEE80211_RADIOTAP_FLAGS: - /* is the CRC visible at the end? - * remove - */ - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) - { - fcs_removed = 1; - caplen -= 4; - } - - if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) - return (0); - - break; - - } - } + /* go through the radiotap arguments we have been given + * by the driver + */ - n = le16_to_cpu(rthdr->it_len); + while (ieee80211_radiotap_iterator_next (&iterator) >= 0) + { - if (n <= 0 || n >= caplen) - return (0); - } + switch (iterator.this_arg_index) + { - caplen -= n; + case IEEE80211_RADIOTAP_TSFT: + ri->ri_mactime = le64_to_cpu (*((uint64_t *) iterator.this_arg)); + break; - //detect fcs at the end, even if the flag wasn't set and remove it - if (0 == fcs_removed && 1== check_crc_buf_osdep(tmpbuf + n, caplen - 4)) - { - caplen -= 4; - } + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + if (!got_signal) + { + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; - memcpy(buf, tmpbuf + n, caplen); + got_signal = 1; + } + break; - if (ri && !got_channel) - ri->ri_channel = linux_get_channel(dev); + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + if (!got_signal) + { + if (*iterator.this_arg < 127) + ri->ri_power = *iterator.this_arg; + else + ri->ri_power = *iterator.this_arg - 255; - return (caplen); -} + got_signal = 1; + } + break; -static int -linux_write(struct Hardware_Infos * dev, unsigned char *buf, unsigned int count) -{ - int ret; - //int usedrtap; - //unsigned short int *p_rtlen; + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + if (!got_noise) + { + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; - //unsigned char * u8aRadiotap = buf; + got_noise = 1; + } + break; - /* Pointer to the radiotap header length field for later use. */ - //p_rtlen = (unsigned short int*) (u8aRadiotap + 2); - //usedrtap = 0; - ret = write(dev->fd_out, buf, count); + case IEEE80211_RADIOTAP_DB_ANTNOISE: + if (!got_noise) + { + if (*iterator.this_arg < 127) + ri->ri_noise = *iterator.this_arg; + else + ri->ri_noise = *iterator.this_arg - 255; - if (0 > ret) - { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno - == ENOMEM) + got_noise = 1; + } + break; + + case IEEE80211_RADIOTAP_ANTENNA: + ri->ri_antenna = *iterator.this_arg; + break; + + case IEEE80211_RADIOTAP_CHANNEL: + ri->ri_channel = *iterator.this_arg; + got_channel = 1; + break; + + case IEEE80211_RADIOTAP_RATE: + ri->ri_rate = (*iterator.this_arg) * 500000; + break; + + case IEEE80211_RADIOTAP_FLAGS: + /* is the CRC visible at the end? + * remove + */ + if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { - usleep(10000); - return (0); + fcs_removed = 1; + caplen -= 4; } - perror("write failed"); - return (-1); - } - - /* radiotap header length is stored little endian on all systems */ - /*if (usedrtap) - ret -= letoh16(*p_rtlen); + if (*iterator.this_arg & IEEE80211_RADIOTAP_F_RX_BADFCS) + return (0); - if (0 > ret) - { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || errno - == ENOMEM) - { - usleep(10000); - return (0); - } + break; + } + } + n = le16_to_cpu (rthdr->it_len); + if (n <= 0 || n >= caplen) + return 0; + } + break; + case ARPHRD_IEEE80211: + /* do nothing? */ + break; + default: + errno = ENOTSUP; + return -1; + } - perror("write failed"); - return (-1); - }*/ + caplen -= n; - return (ret); + //detect fcs at the end, even if the flag wasn't set and remove it + if ((0 == fcs_removed) && (1 == check_crc_buf_osdep (tmpbuf + n, caplen - 4))) + { + caplen -= 4; + } + memcpy (buf, tmpbuf + n, caplen); + if (!got_channel) + ri->ri_channel = linux_get_channel (dev); + + return caplen; } +/** + * function to open the device for read/write + * @param dev pointer to the device struct + * @return 0 on success + */ static int -openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, - uint8_t *mac) +openraw (struct Hardware_Infos *dev) { struct ifreq ifr; struct iwreq wrq; @@ -470,632 +434,607 @@ openraw(struct Hardware_Infos * dev, char * iface, int fd, int * arptype, struct sockaddr_ll sll; /* find the interface index */ + memset (&ifr, 0, sizeof (ifr)); + strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ); + if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr)) + { + fprintf (stderr, + "Line: 381 ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); - - if (0 > ioctl(fd, SIOCGIFINDEX, &ifr)) - { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFINDEX) failed"); - return (1); - } - - memset(&sll, 0, sizeof(sll)); + /* lookup the hardware type */ + memset (&sll, 0, sizeof (sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; - - sll.sll_protocol = htons(ETH_P_ALL); - - /* lookup the hardware type */ - - if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) - { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFHWADDR) failed"); - return (1); - } + sll.sll_protocol = htons (ETH_P_ALL); + if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) + { + fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } /* lookup iw mode */ - memset(&wrq, 0, sizeof(struct iwreq)); - strncpy(wrq.ifr_name, iface, IFNAMSIZ); - - if (0 > ioctl(fd, SIOCGIWMODE, &wrq)) - { - /* most probably not supported (ie for rtap ipw interface) * - * so just assume its correctly set... */ - wrq.u.mode = IW_MODE_MONITOR; - } - - if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_FULL) || (wrq.u.mode != IW_MODE_MONITOR)) - { - printf("Error: %s not in monitor mode\n", iface); - return (1); - } + memset (&wrq, 0, sizeof (struct iwreq)); + strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ); + if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq)) + { + /* most probably not supported (ie for rtap ipw interface) * + * so just assume its correctly set... */ + wrq.u.mode = IW_MODE_MONITOR; + } + + if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) || + (wrq.u.mode != IW_MODE_MONITOR)) + { + fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n", + IFNAMSIZ, dev->iface); + return 1; + } /* Is interface st to up, broadcast & running ? */ if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags) - { - /* Bring interface up*/ - ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; - - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - { - perror("ioctl(SIOCSIFFLAGS) failed"); - return (1); - } - } - /* bind the raw socket to the interface */ + { + /* Bring interface up */ + ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING; - if (0 > bind(fd, (struct sockaddr *) &sll, sizeof(sll))) + if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr)) { - printf("Interface %s: \n", iface); - perror("bind(ETH_P_ALL) failed"); - return (1); - } - - /* lookup the hardware type */ - - if (0 > ioctl(fd, SIOCGIFHWADDR, &ifr)) - { - printf("Interface %s: \n", iface); - perror("ioctl(SIOCGIFHWADDR) failed"); - return (1); + fprintf (stderr, + "Line: 434 ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; } + } - memcpy(mac, (unsigned char*) ifr.ifr_hwaddr.sa_data, 6); - - *arptype = ifr.ifr_hwaddr.sa_family; + /* bind the raw socket to the interface */ + if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll))) + { + fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ, + dev->iface, strerror (errno)); + return 1; + } - if (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211 && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_PRISM && ifr.ifr_hwaddr.sa_family - != ARPHRD_IEEE80211_FULL) - { - if (1 == ifr.ifr_hwaddr.sa_family) - fprintf(stderr, "\nARP linktype is set to 1 (Ethernet) "); - else - fprintf(stderr, "\nUnsupported hardware link type %4d ", - ifr.ifr_hwaddr.sa_family); - - fprintf(stderr, "- expected ARPHRD_IEEE80211,\nARPHRD_IEEE80211_" - "FULL or ARPHRD_IEEE80211_PRISM instead. Make\n" - "sure RFMON is enabled: run 'airmon-ng start %s" - " <#>'\nSysfs injection support was not found " - "either.\n\n", iface); - return (1); - } + /* lookup the hardware type */ + if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr)) + { + fprintf (stderr, + "Line: 457 ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n", + IFNAMSIZ, dev->iface, strerror (errno)); + return 1; + } + + memcpy (dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE); + dev->arptype_in = ifr.ifr_hwaddr.sa_family; + if ((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) && + (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) + { + fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n", + ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface); + return 1; + } /* enable promiscuous mode */ - - memset(&mr, 0, sizeof(mr)); + memset (&mr, 0, sizeof (mr)); mr.mr_ifindex = sll.sll_ifindex; mr.mr_type = PACKET_MR_PROMISC; + if (0 != + setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, + sizeof (mr))) + { + fprintf (stderr, "Failed to enable promiscuous mode on interface `%.*s'\n", + IFNAMSIZ, dev->iface); + return 1; + } - if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) - { - perror("setsockopt(PACKET_MR_PROMISC) failed"); - return (1); - } - - return (0); + return 0; } -int -wlaninit(struct Hardware_Infos * dev, char *iface) +/** + * function to prepare the helper, e.g. sockets, device... + * @param dev struct for the device + * @param iface name of the interface + * @return 0 on success + */ +static int +wlaninit (struct Hardware_Infos *dev, const char *iface) { char strbuf[512]; + struct stat sbuf; + int ret; - dev->fd_out = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (0 > dev->fd_out) - { - perror("socket(PF_PACKET) failed at fd_out"); - goto close_in; - } - - /* figure out device type */ - - /* mac80211 radiotap injection - * detected based on interface called mon... - * since mac80211 allows multiple virtual interfaces - * - * note though that the virtual interfaces are ultimately using a - * single physical radio: that means for example they must all - * operate on the same channel - */ + dev->fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)); + if (0 > dev->fd_raw) + { + fprintf (stderr, "Failed to create raw socket: %s\n", strerror (errno)); + return 1; + } + if (dev->fd_raw >= FD_SETSIZE) + { + fprintf (stderr, "File descriptor too large for select (%d > %d)\n", + dev->fd_raw, FD_SETSIZE); + close (dev->fd_raw); + return 1; + } /* mac80211 stack detection */ - memset(strbuf, 0, sizeof(strbuf)); - snprintf(strbuf, sizeof(strbuf) - 1, - "ls /sys/class/net/%s/phy80211/subsystem >/dev/null 2>/dev/null", iface); - - if (0 == system(strbuf)) - dev->drivertype = DT_MAC80211_RT; - - else - { - // At the moment only mac80211 tested - fprintf(stderr, "only mac80211 stack supported, exiting.\n"); - return 1; - } - -#ifdef DEBUG - fprintf(stderr, "Interface %s -> driver: %s\n", iface, - szaDriverTypes[dev->drivertype]); -#endif - - if (openraw(dev, iface, dev->fd_out, &dev->arptype_in, dev->pl_mac) != 0) - { - goto close_out; - } - - dev->fd_in = dev->fd_out; - dev->iface = GNUNET_malloc(sizeof(char) *6); - strncpy(dev->iface, iface, sizeof(char) * 6); - - + ret = + snprintf (strbuf, sizeof (strbuf), "/sys/class/net/%s/phy80211/subsystem", + iface); + if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf))) + { + fprintf (stderr, "Did not find 802.11 interface `%s'. Exiting.\n", iface); + close (dev->fd_raw); + return 1; + } + strncpy (dev->iface, iface, IFNAMSIZ); + if (0 != openraw (dev)) + { + close (dev->fd_raw); + return 1; + } return 0; - close_out: close(dev->fd_out); - close_in: close(dev->fd_in); - return 1; } + /** - * function to test incoming packets mac - * @param buf buffer of the packet - * @param dev pointer to the Hardware_Infos struct - * @return 0 if macs are okay, 1 if macs are wrong + * Function to test incoming packets mac for being our own. + * + * @param u8aIeeeHeader buffer of the packet + * @param dev the Hardware_Infos struct + * @return 0 if mac belongs to us, 1 if mac is for another target */ - static int -mac_test(unsigned char * buf, struct Hardware_Infos * dev) +mac_test (const struct ieee80211_frame *u8aIeeeHeader, + const struct Hardware_Infos *dev) { - struct ieee80211_frame * u8aIeeeHeader; - u8aIeeeHeader = (struct ieee80211_frame *) buf; - if (0 == memcmp(u8aIeeeHeader->i_addr3, &mac_bssid, 6)) - { - if (0 == memcmp(u8aIeeeHeader->i_addr1, dev->pl_mac, 6)) - { - return 0; - } - - if (0 == memcmp(u8aIeeeHeader->i_addr1, &bc_all_mac, 6)) - { - return 0; - } - } - + if (0 != memcmp (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE)) + return 1; + if (0 == memcmp (u8aIeeeHeader->i_addr1, dev->pl_mac, MAC_ADDR_SIZE)) + return 0; + if (0 == memcmp (u8aIeeeHeader->i_addr1, &bc_all_mac, MAC_ADDR_SIZE)) + return 0; return 1; } + /** * function to set the wlan header to make attacks more difficult - * @param buf buffer of the packet + * @param u8aIeeeHeader pointer to the header of the packet * @param dev pointer to the Hardware_Infos struct */ - static void -mac_set(unsigned char * buf, struct Hardware_Infos * dev) +mac_set (struct ieee80211_frame *u8aIeeeHeader, + const struct Hardware_Infos *dev) { - struct ieee80211_frame * u8aIeeeHeader; - u8aIeeeHeader = (struct ieee80211_frame *) buf; - u8aIeeeHeader->i_fc[0] = 0x08; u8aIeeeHeader->i_fc[1] = 0x00; - - memcpy(u8aIeeeHeader->i_addr2, dev->pl_mac, 6); - memcpy(u8aIeeeHeader->i_addr3, &mac_bssid, 6); + memcpy (u8aIeeeHeader->i_addr2, dev->pl_mac, MAC_ADDR_SIZE); + memcpy (u8aIeeeHeader->i_addr3, &mac_bssid, MAC_ADDR_SIZE); } +/** + * function to process the data from the stdin + * @param cls pointer to the device struct + * @param client not used + * @param hdr pointer to the start of the packet + */ static void -stdin_send_hw(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) +stdin_send_hw (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) { - struct Hardware_Infos * dev = cls; - struct sendbuf *write_pout = dev->write_pout; - struct Radiotap_Send * header = (struct Radiotap_Send *) &hdr[1]; - unsigned char * wlanheader; - - int sendsize; - - unsigned char u8aRadiotap[] = - { 0x00, 0x00, // <-- radiotap version - 0x0c, 0x00, // <- radiotap header length - 0x04, 0x80, 0x00, 0x00, // <-- bitmap - 0x00, // <-- rate - 0x00, // <-- padding for natural alignment - 0x18, 0x00, // <-- TX flags - }; - - sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send) - - sizeof(struct GNUNET_MessageHeader); - - if (MAXLINE * 2 < sendsize) - { - fprintf(stderr, "Function stdin_send: Packet too big for buffer\n"); - exit(1); - } - - if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type)) - { - fprintf(stderr, "Function stdin_send: wrong packet type\n"); - exit(1); - } - - if ( sizeof(struct ieee80211_frame) - + sizeof(struct GNUNET_MessageHeader) > sendsize) - { - fprintf(stderr, "Function stdin_send: packet too small\n"); - exit(1); - } - - u8aRadiotap[2] = htole16(sizeof(u8aRadiotap)); - u8aRadiotap[8] = header->rate; - - switch (dev->drivertype) - { - - case DT_MAC80211_RT: - memcpy(write_pout->buf, u8aRadiotap, sizeof(u8aRadiotap)); - memcpy(write_pout->buf + sizeof(u8aRadiotap), &header[1], sendsize); - - wlanheader = write_pout->buf + sizeof(u8aRadiotap); - mac_set(wlanheader, dev); - - sendsize += sizeof(u8aRadiotap); - - break; - default: - break; - } - - write_pout->size = sendsize; + struct Hardware_Infos *dev = cls; + struct sendbuf *write_pout = &dev->write_pout; + struct Radiotap_Send *header = (struct Radiotap_Send *) &hdr[1]; + struct ieee80211_frame *wlanheader; + size_t sendsize; + + // struct? // FIXME: make nice... + struct RadioTapheader rtheader; + + rtheader.header.it_version = 0; + rtheader.header.it_len = htole16 (0x0c); + rtheader.header.it_present = htole32 (0x00008004); + rtheader.rate = 0x00; + rtheader.pad1 = 0x00; + rtheader.txflags = + htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ); + + /* { 0x00, 0x00, <-- radiotap version + * 0x0c, 0x00, <- radiotap header length + * 0x04, 0x80, 0x00, 0x00, <-- bitmap + * 0x00, <-- rate + * 0x00, <-- padding for natural alignment + * 0x18, 0x00, <-- TX flags + * }; */ + + sendsize = ntohs (hdr->size); + if (sendsize < + sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader)) + { + fprintf (stderr, "Function stdin_send_hw: malformed packet (too small)\n"); + exit (1); + } + sendsize -= + sizeof (struct Radiotap_Send) + sizeof (struct GNUNET_MessageHeader); + + if (MAXLINE < sendsize) + { + fprintf (stderr, "Function stdin_send_hw: Packet too big for buffer\n"); + exit (1); + } + if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs (hdr->type)) + { + fprintf (stderr, "Function stdin_send: wrong packet type\n"); + exit (1); + } + + rtheader.header.it_len = htole16 (sizeof (rtheader)); + rtheader.rate = header->rate; + memcpy (write_pout->buf, &rtheader, sizeof (rtheader)); + memcpy (write_pout->buf + sizeof (rtheader), &header[1], sendsize); + /* payload contains MAC address, but we don't trust it, so we'll + * overwrite it with OUR MAC address again to prevent mischief */ + wlanheader = (struct ieee80211_frame *) (write_pout->buf + sizeof (rtheader)); + mac_set (wlanheader, dev); + write_pout->size = sendsize + sizeof (rtheader); } +#if 0 +/** + * Function to make test packets with special options + * @param buf buffer to write the data to + * @param dev device to send the data from + * @return size of packet (what should be send) + */ static int -maketest(unsigned char * buf, struct Hardware_Infos * dev) +maketest (unsigned char *buf, struct Hardware_Infos *dev) { - uint16_t * tmp16; + uint16_t *tmp16; static uint16_t seqenz = 0; static int first = 0; const int rate = 11000000; - static const char - txt[] = - "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211"; - - unsigned char u8aRadiotap[] = - { 0x00, 0x00, // <-- radiotap version - 0x00, 0x00, // <- radiotap header length - 0x04, 0x80, 0x02, 0x00, // <-- bitmap - 0x00, // <-- rate - 0x00, // <-- padding for natural alignment - 0x10, 0x00, // <-- TX flags - 0x04 //retries - }; + static const char txt[] = + "Hallo1Hallo2 Hallo3 Hallo4...998877665544332211Hallo1Hallo2 Hallo3 Hallo4...998877665544332211"; + + unsigned char u8aRadiotap[] = { 0x00, 0x00, // <-- radiotap version + 0x00, 0x00, // <- radiotap header length + 0x04, 0x80, 0x02, 0x00, // <-- bitmap + 0x00, // <-- rate + 0x00, // <-- padding for natural alignment + 0x10, 0x00, // <-- TX flags + 0x04 //retries + }; /*uint8_t u8aRadiotap[] = - { - 0x00, 0x00, // <-- radiotap version - 0x19, 0x00, // <- radiotap header length - 0x6f, 0x08, 0x00, 0x00, // <-- bitmap - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp - 0x00, // <-- flags (Offset +0x10) - 0x6c, // <-- rate (0ffset +0x11) - 0x71, 0x09, 0xc0, 0x00, // <-- channel - 0xde, // <-- antsignal - 0x00, // <-- antnoise - 0x01, // <-- antenna - };*/ + * { + * 0x00, 0x00, // <-- radiotap version + * 0x19, 0x00, // <- radiotap header length + * 0x6f, 0x08, 0x00, 0x00, // <-- bitmap + * 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp + * 0x00, // <-- flags (Offset +0x10) + * 0x6c, // <-- rate (0ffset +0x11) + * 0x71, 0x09, 0xc0, 0x00, // <-- channel + * 0xde, // <-- antsignal + * 0x00, // <-- antnoise + * 0x01, // <-- antenna + * }; */ u8aRadiotap[8] = (rate / 500000); - u8aRadiotap[2] = htole16(sizeof(u8aRadiotap)); + u8aRadiotap[2] = htole16 (sizeof (u8aRadiotap)); static struct ieee80211_frame u8aIeeeHeader; - uint8_t u8aIeeeHeader_def[] = - { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; - // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data - // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; - 0x00, 0x00, // Duration/ID - - //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver - 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver - 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender - //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4, - 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid - 0x10, 0x86, //Sequence Control - }; + uint8_t u8aIeeeHeader_def[] = { 0x08, 0x00, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; + // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data + // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; + 0x00, 0x00, // Duration/ID + + //0x00, 0x1f, 0x3f, 0xd1, 0x8e, 0xe6, // mac1 - in this case receiver + 0x00, 0x1d, 0xe0, 0xb0, 0x17, 0xdf, // mac1 - in this case receiver + 0xC0, 0x3F, 0x0E, 0x44, 0x2D, 0x51, // mac2 - in this case sender + //0x02, 0x1d, 0xe0, 0x00, 0x01, 0xc4, + 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case bssid + 0x10, 0x86, //Sequence Control + }; if (0 == first) - { - memcpy(&u8aIeeeHeader, u8aIeeeHeader_def, sizeof(struct ieee80211_frame)); - memcpy(u8aIeeeHeader.i_addr2, dev->pl_mac, 6); - first = 1; - } - - tmp16 = (uint16_t*) u8aIeeeHeader.i_dur; - *tmp16 - = (uint16_t) htole16((sizeof(txt) + sizeof(struct ieee80211_frame) * 1000000) / rate + 290); - tmp16 = (uint16_t*) u8aIeeeHeader.i_seq; - *tmp16 = (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16(seqenz) - << IEEE80211_SEQ_SEQ_SHIFT); + { + memcpy (&u8aIeeeHeader, u8aIeeeHeader_def, sizeof (struct ieee80211_frame)); + memcpy (u8aIeeeHeader.i_addr2, dev->pl_mac, MAC_ADDR_SIZE); + first = 1; + } + + tmp16 = (uint16_t *) u8aIeeeHeader.i_dur; + *tmp16 = + (uint16_t) + htole16 ((sizeof (txt) + + sizeof (struct ieee80211_frame) * 1000000) / rate + 290); + tmp16 = (uint16_t *) u8aIeeeHeader.i_seq; + *tmp16 = + (*tmp16 & IEEE80211_SEQ_FRAG_MASK) | (htole16 (seqenz) << + IEEE80211_SEQ_SEQ_SHIFT); seqenz++; - memcpy(buf, u8aRadiotap, sizeof(u8aRadiotap)); - memcpy(buf + sizeof(u8aRadiotap), &u8aIeeeHeader, sizeof(u8aIeeeHeader)); - memcpy(buf + sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader), txt, sizeof(txt)); - return sizeof(u8aRadiotap) + sizeof(u8aIeeeHeader) + sizeof(txt); + memcpy (buf, u8aRadiotap, sizeof (u8aRadiotap)); + memcpy (buf + sizeof (u8aRadiotap), &u8aIeeeHeader, sizeof (u8aIeeeHeader)); + memcpy (buf + sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader), txt, + sizeof (txt)); + return sizeof (u8aRadiotap) + sizeof (u8aIeeeHeader) + sizeof (txt); } +#endif -int -hardwaremode(int argc, char *argv[]) -{ +/** + * Function to start the hardware for the wlan helper + * @param argc number of arguments + * @param argv arguments + * @return returns one on error + */ +static int +hardwaremode (int argc, char *argv[]) +{ uid_t uid; struct Hardware_Infos dev; - struct Radiotap_rx * rxinfo; - uint8_t * mac = dev.pl_mac; - int fdpin, fdpout; - - struct GNUNET_MessageHeader * header; - - signal(SIGINT, &sigfunc_hw); - signal(SIGTERM, &sigfunc_hw); - - if (wlaninit(&dev, argv[1])) - { - return 1; - } - - uid = getuid(); - //if (0 != setresuid(uid, uid, uid)) - //{ - // fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno)); - /* not critical, continue anyway */ - //} - - unsigned char * datastart; char readbuf[MAXLINE]; - int readsize = 0; struct sendbuf write_std; - write_std.size = 0; - write_std.pos = 0; - - struct sendbuf write_pout; - write_pout.size = 0; - write_pout.pos = 0; - - dev.write_pout = &write_pout; - - int ret = 0; - int maxfd = 0; - + ssize_t ret; + int maxfd; fd_set rfds; fd_set wfds; - struct timeval tv; int retval; - - struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst; - - fdpin = dev.fd_in; - fdpout = dev.fd_out; - - stdin_mst = GNUNET_SERVER_mst_create(&stdin_send_hw, &dev); - - //send mac first - - write_std.size = send_mac_to_plugin((char *) &write_std.buf, mac); - - //wait - tv.tv_sec = 2; - tv.tv_usec = 0; - retval = select(0, NULL, NULL, NULL, &tv); - - while (0 == closeprog) + int stdin_open; + struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst; + + if (0 != wlaninit (&dev, argv[1])) + return 1; + uid = getuid (); + if (0 != setresuid (uid, uid, uid)) + { + fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); + /* not critical, continue anyway */ + } + + dev.write_pout.size = 0; + dev.write_pout.pos = 0; + stdin_mst = GNUNET_SERVER_mst_create (&stdin_send_hw, &dev); + + /* send mac to STDOUT first */ + write_std.pos = 0; + write_std.size = send_mac_to_plugin ((char *) &write_std.buf, dev.pl_mac); + stdin_open = 1; + + while (1) + { + maxfd = -1; + FD_ZERO (&rfds); + if ((0 == dev.write_pout.size) && (1 == stdin_open)) { + FD_SET (STDIN_FILENO, &rfds); + maxfd = MAX (maxfd, STDIN_FILENO); + } + if (0 == write_std.size) + { + FD_SET (dev.fd_raw, &rfds); + maxfd = MAX (maxfd, dev.fd_raw); + } + FD_ZERO (&wfds); + if (0 < write_std.size) + { + FD_SET (STDOUT_FILENO, &wfds); + maxfd = MAX (maxfd, STDOUT_FILENO); + } + if (0 < dev.write_pout.size) + { + FD_SET (dev.fd_raw, &wfds); + maxfd = MAX (maxfd, dev.fd_raw); + } + retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); + if ((-1 == retval) && (EINTR == errno)) + continue; + if (0 > retval) + { + fprintf (stderr, "select failed: %s\n", strerror (errno)); + break; + } - //write_pout.size = maketest(write_pout.buf, &dev); - //tv.tv_sec = 2; - //tv.tv_usec = 0; - //select(0, NULL, NULL, NULL, &tv); - - maxfd = 0; - - //set timeout - tv.tv_sec = 5; - tv.tv_usec = 0; - - FD_ZERO(&rfds); - // if output queue is empty - if (0 == write_pout.size) - { - FD_SET(STDIN_FILENO, &rfds); - - } - if (0 == write_std.size) - { - FD_SET(fdpin, &rfds); - maxfd = fdpin; - } - FD_ZERO(&wfds); - // if there is something to write - if (0 < write_std.size) - { - FD_SET(STDOUT_FILENO, &wfds); - maxfd = MAX(maxfd, STDOUT_FILENO); - } - - if (0 < write_pout.size) - { - FD_SET(fdpout, &wfds); - maxfd = MAX(maxfd, fdpout); - } - - retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv); - - if (-1 == retval && EINTR == errno) - { - continue; - } - if (0 > retval) - { - fprintf(stderr, "select failed: %s\n", strerror(errno)); - exit(1); - } - - if (FD_ISSET(STDOUT_FILENO, &wfds)) - { - ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, - write_std.size - write_std.pos); - - if (0 > ret) - { - closeprog = 1; - fprintf(stderr, "Write ERROR to STDOUT\n"); - goto end; - } - else - { - write_std.pos += ret; - // check if finished - if (write_std.pos == write_std.size) - { - write_std.pos = 0; - write_std.size = 0; - } - } - } - - if (FD_ISSET(fdpout, &wfds)) - { - - ret = linux_write(&dev, write_pout.buf, write_pout.size); - - if (0 > ret) - { - closeprog = 1; - fprintf(stderr, "Write ERROR to fdpout\n"); - } - else - { - write_pout.pos += ret; - // check if finished - if (write_pout.pos != write_pout.size && ret != 0) - { - closeprog = 1; - fprintf(stderr, - "Write ERROR packet not in one piece send: %u, %u\n", - write_pout.pos, write_pout.size); - } - else if (write_pout.pos == write_pout.size) - { - write_pout.pos = 0; - write_pout.size = 0; - } - - } - } - - if (FD_ISSET(STDIN_FILENO, &rfds)) - { - readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf)); - - if (0 > readsize) - { - closeprog = 1; - fprintf(stderr, "Read ERROR to STDIN_FILENO\n"); - } - else if (0 < readsize) - { - GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize, - GNUNET_NO, GNUNET_NO); - - } - else - { - //eof - closeprog = 1; - } - } + if (FD_ISSET (STDOUT_FILENO, &wfds)) + { + ret = + write (STDOUT_FILENO, write_std.buf + write_std.pos, + write_std.size - write_std.pos); + if (0 > ret) + { + fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno)); + break; + } + write_std.pos += ret; + if (write_std.pos == write_std.size) + { + write_std.pos = 0; + write_std.size = 0; + } + } - if (FD_ISSET(fdpin, &rfds)) - { - rxinfo = (struct Radiotap_rx *) (write_std.buf - + sizeof(struct GNUNET_MessageHeader)); - datastart = (unsigned char *) write_std.buf - + sizeof(struct Radiotap_rx) - + sizeof(struct GNUNET_MessageHeader); - - readsize = linux_read(&dev, datastart, sizeof(write_std.buf) - - sizeof(struct Radiotap_rx) - - sizeof(struct GNUNET_MessageHeader), rxinfo); - - if (0 > readsize) - { - closeprog = 1; - fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno)); - closeprog = 1; - } - else if (0 < readsize) - { - if (1 == mac_test(datastart, &dev)) - { - // mac wrong - write_std.pos = 0; - write_std.size = 0; - } - else - { - header = (struct GNUNET_MessageHeader *) write_std.buf; - write_std.size = readsize - + sizeof(struct GNUNET_MessageHeader) - + sizeof(struct Radiotap_rx); - header->size = htons(write_std.size); - header->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); - fprintf(stderr, "Got packet with size: %u, size std %u\n", - readsize, write_std.size); - - } - } - } + if (FD_ISSET (dev.fd_raw, &wfds)) + { + ret = write (dev.fd_raw, dev.write_pout.buf, dev.write_pout.size); + if (0 > ret) + { + fprintf (stderr, + "Line %u: Failed to write to WLAN device: %s, Message-Size: %u\n", + __LINE__, strerror (errno), dev.write_pout.size); + break; + } + dev.write_pout.pos += ret; + if ((dev.write_pout.pos != dev.write_pout.size) && (ret != 0)) + { + fprintf (stderr, "Line %u: Write error, partial send: %u/%u\n", + __LINE__, dev.write_pout.pos, dev.write_pout.size); + break; + } + if (dev.write_pout.pos == dev.write_pout.size) + { + dev.write_pout.pos = 0; + dev.write_pout.size = 0; + } + } + if (FD_ISSET (STDIN_FILENO, &rfds)) + { + ret = read (STDIN_FILENO, readbuf, sizeof (readbuf)); + if (0 > ret) + { + fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno)); + break; + } + if (0 == ret) + { + /* stop reading... */ + stdin_open = 0; + } + GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, ret, GNUNET_NO, + GNUNET_NO); } - GNUNET_SERVER_mst_destroy(stdin_mst); - return 0; + if (FD_ISSET (dev.fd_raw, &rfds)) + { + struct GNUNET_MessageHeader *header; + struct Radiotap_rx *rxinfo; + struct ieee80211_frame *datastart; + + header = (struct GNUNET_MessageHeader *) write_std.buf; + rxinfo = (struct Radiotap_rx *) &header[1]; + datastart = (struct ieee80211_frame *) &rxinfo[1]; + ret = + linux_read (&dev, (unsigned char *) datastart, + sizeof (write_std.buf) - sizeof (struct Radiotap_rx) - + sizeof (struct GNUNET_MessageHeader), rxinfo); + if (0 > ret) + { + fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno)); + break; + } + if ((0 < ret) && (0 == mac_test (datastart, &dev))) + { + write_std.size = + ret + sizeof (struct GNUNET_MessageHeader) + + sizeof (struct Radiotap_rx); + header->size = htons (write_std.size); + header->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); + } + } - end: GNUNET_SERVER_mst_destroy(stdin_mst); + } + /* Error handling, try to clean up a bit at least */ + GNUNET_SERVER_mst_destroy (stdin_mst); + close (dev.fd_raw); return 1; - } +/** + * main function of the helper + * @param argc number of arguments + * @param argv arguments + * @return 0 on success, 1 on error + */ int -main(int argc, char *argv[]) +main (int argc, char *argv[]) { - int ret = 0; - if (3 != argc) - { - fprintf( - stderr, - "This program must be started with the interface and the operating mode as argument.\n"); - usage(); - return 1; - } - - if (strstr(argv[2], "1") || strstr(argv[2], "2")) - { - - ret = testmode(argc, argv); - } - else - { + if (2 != argc) + { + fprintf (stderr, + "This program must be started with the interface as argument.\nThis program was compiled at ----- %s ----\n", + __TIMESTAMP__); + fprintf (stderr, "Usage: interface-name\n" "\n"); + return 1; + } + return hardwaremode (argc, argv); +} - ret = hardwaremode(argc, argv); - } +/* + * Copyright (c) 2008, Thomas d'Otreppe + * + * Common OSdep stuff + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ - return ret; - maketest(NULL, NULL); +/** + * Return the frequency in Mhz from a channel number + * @param channel number of the channel + * @return frequency of the channel + */ +int +getFrequencyFromChannel (int channel) +{ + static int frequencies[] = { + -1, // No channel 0 + 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, + 2472, 2484, + -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) + 5170, 5175, 5180, 5185, 5190, 5195, 5200, 5205, 5210, 5215, 5220, 5225, + 5230, 5235, 5240, 5245, + 5250, 5255, 5260, 5265, 5270, 5275, 5280, 5285, 5290, 5295, 5300, 5305, + 5310, 5315, 5320, 5325, + 5330, 5335, 5340, 5345, 5350, 5355, 5360, 5365, 5370, 5375, 5380, 5385, + 5390, 5395, 5400, 5405, + 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5455, 5460, 5465, + 5470, 5475, 5480, 5485, + 5490, 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545, + 5550, 5555, 5560, 5565, + 5570, 5575, 5580, 5585, 5590, 5595, 5600, 5605, 5610, 5615, 5620, 5625, + 5630, 5635, 5640, 5645, + 5650, 5655, 5660, 5665, 5670, 5675, 5680, 5685, 5690, 5695, 5700, 5705, + 5710, 5715, 5720, 5725, + 5730, 5735, 5740, 5745, 5750, 5755, 5760, 5765, 5770, 5775, 5780, 5785, + 5790, 5795, 5800, 5805, + 5810, 5815, 5820, 5825, 5830, 5835, 5840, 5845, 5850, 5855, 5860, 5865, + 5870, 5875, 5880, 5885, + 5890, 5895, 5900, 5905, 5910, 5915, 5920, 5925, 5930, 5935, 5940, 5945, + 5950, 5955, 5960, 5965, + 5970, 5975, 5980, 5985, 5990, 5995, 6000, 6005, 6010, 6015, 6020, 6025, + 6030, 6035, 6040, 6045, + 6050, 6055, 6060, 6065, 6070, 6075, 6080, 6085, 6090, 6095, 6100 + }; + + return ((channel > 0) && + (channel < + sizeof (frequencies) / sizeof (int))) ? frequencies[channel] : -1; } +/** + * Return the channel from the frequency (in Mhz) + * @param frequency of the channel + * @return number of the channel + */ +int +getChannelFromFrequency (int frequency) +{ + if (frequency >= 2412 && frequency <= 2472) + return (frequency - 2407) / 5; + else if (frequency == 2484) + return 14; + else if (frequency >= 5000 && frequency <= 6100) + return (frequency - 5000) / 5; + else + return -1; +}