/*
This file is part of GNUnet.
- (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
- Copyright (C) 2009 Thomas d'Otreppe
+ Copyright Copyright (C) 2009 Thomas d'Otreppe
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
* parts taken from aircrack-ng, parts changend.
*/
#include "gnunet_config.h"
+#define SOCKTYPE int
+#define FDTYPE int
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "plugin_transport_wlan.h"
/**
- * Packet format type for the messages we receive from
+ * Packet format type for the messages we receive from
+ * the kernel. This is for Ethernet 10Mbps format (no
+ * performance information included).
+ */
+#define ARPHRD_ETHER 1
+
+
+/**
+ * Packet format type for the messages we receive from
* the kernel. This is for plain messages (with no
* performance information included).
*/
#define ARPHRD_IEEE80211 801
+
/**
- * Packet format type for the messages we receive from
+ * Packet format type for the messages we receive from
* the kernel. This is for the PRISM format.
*/
#define ARPHRD_IEEE80211_PRISM 802
/**
- * Packet format type for the messages we receive from
+ * Packet format type for the messages we receive from
* the kernel. This is for messages with a
* 'struct Ieee80211RadiotapHeader' (see below).
*/
* Drivers appear to use a 64bit counter to hold mactime internal
* the then fill the prism header with the lower 32 bits
*/
-#define PRISM_DID_MACTIME 0x2041
+#define PRISM_DID_MACTIME 0x2041
/**
* Channel element
*/
-#define PRISM_DID_CHANNEL 0x3041
+#define PRISM_DID_CHANNEL 0x3041
/**
* Signal element. Should be the signal strength in dbm, some people
* suggest that instead "100 - (strength in dbm)" is used (to make this
* a positive integer).
*/
-#define PRISM_DID_SIGNAL 0x6041
+#define PRISM_DID_SIGNAL 0x6041
/**
* Noise element
*/
-#define PRISM_DID_NOISE 0x7041
+#define PRISM_DID_NOISE 0x7041
/**
* Rate element, in units/multiples of 500Khz
*/
-#define PRISM_DID_RATE 0x8041
+#define PRISM_DID_RATE 0x8041
/**
* Value is set (supplied)
*/
-#define PRISM_STATUS_OK 0
+#define PRISM_STATUS_OK 0
/**
* Value not supplied.
* This has a different ID for each parameter, see
* PRISM_DID_* constants.
*/
- uint32_t did;
-
+ uint32_t did;
+
/**
* See PRISM_STATUS_*-constants. Note that they are unusual: 0 = set; 1 = not set
*/
- uint16_t status;
-
+ uint16_t status;
+
/**
* length of data (which is always a uint32_t, but presumably this can be used
* to specify that fewer bytes are used (with values in 'len' from 0-4). We
* ignore this field.
*/
- uint16_t len;
+ uint16_t len;
/**
* The data value
*/
- uint32_t data;
+ uint32_t data;
} __attribute__ ((packed));
* We expect this to be a PRISM_MSGCODE_*.
*/
uint32_t msgcode;
-
+
/**
* The length of the entire header.
*/
- uint32_t msglen;
+ uint32_t msglen;
/**
* Name of the device that captured the packet.
*/
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
- /**
+ /**
* IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index
*
* Unitless indication of the Rx/Tx antenna for this packet.
*/
IEEE80211_RADIOTAP_RX_FLAGS = 14,
- /**
+ /**
* IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
*
- * Properties of transmitted frames. See flags defined below.
+ * Properties of transmitted frames. See flags defined below.
*/
IEEE80211_RADIOTAP_TX_FLAGS = 15,
};
/**
- * Bitmask indicating an extension of the bitmask is used.
+ * Bitmask indicating an extension of the bitmask is used.
* (Mask corresponding to IEEE80211_RADIOTAP_EXT).
*/
#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT)
*
* Frame was sent/received with short preamble
*/
-#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
+#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
/**
* Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
*
* Frame was sent/received with WEP encryption
*/
-#define IEEE80211_RADIOTAP_F_WEP 0x04
+#define IEEE80211_RADIOTAP_F_WEP 0x04
/**
* Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
*
* Frame was sent/received with fragmentation
*/
-#define IEEE80211_RADIOTAP_F_FRAG 0x08
+#define IEEE80211_RADIOTAP_F_FRAG 0x08
/**
* Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
*
* Frame includes FCS (CRC at the end that needs to be removeD).
*/
-#define IEEE80211_RADIOTAP_F_FCS 0x10
+#define IEEE80211_RADIOTAP_F_FCS 0x10
/**
* Bit in IEEE80211_RADIOTAP_FLAGS (which we might get
* Frame has padding between 802.11 header and payload
* (to 32-bit boundary)
*/
-#define IEEE80211_RADIOTAP_F_DATAPAD 0x20
+#define IEEE80211_RADIOTAP_F_DATAPAD 0x20
/**
* For IEEE80211_RADIOTAP_RX_FLAGS:
* frame failed crc check
*/
-#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
+#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
/**
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
* failed due to excessive retries
*/
-#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
+#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
/**
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
* used cts 'protection'
*/
-#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
+#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
/**
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
- * used rts/cts handshake
+ * used rts/cts handshake
*/
-#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
+#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
/**
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
/**
* For IEEE80211_RADIOTAP_TX_FLAGS ('txflags' in 'struct RadiotapTransmissionHeader'):
- * sequence number handled by userspace
+ * sequence number handled by userspace
*/
#define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010
uint8_t it_version;
/**
- * Padding. Set to 0.
+ * Padding. Set to 0.
*/
uint8_t it_pad;
/**
- * Format of the header we need to prepend to messages to be sent to the
+ * Format of the header we need to prepend to messages to be sent to the
* Kernel.
*/
struct RadiotapTransmissionHeader
* destination? Always smaller than 'size'.
*/
size_t pos;
-
+
/**
* Buffered data; twice the maximum allowed message size as we add some
* headers.
* @param cls closure
* @param message the actual message
*/
-typedef void (*MessageTokenizerCallback) (void *cls,
+typedef void (*MessageTokenizerCallback) (void *cls,
const struct
GNUNET_MessageHeader *
message);
*/
static int
ieee80211_radiotap_iterator_init (struct Ieee80211RadiotapHeaderIterator *iterator,
- const struct Ieee80211RadiotapHeader *radiotap_header,
+ const struct Ieee80211RadiotapHeader *radiotap_header,
size_t max_length)
{
if ( (iterator == NULL) ||
/* need padding (by 'wanted_alignment - unalignment') */
iterator->arg_index += wanted_alignment - unalignment;
}
-
+
/*
* this is what we will return to user, but we need to
* move on first so next call has something fresh to test
- */
+ */
iterator->this_arg_index = iterator->arg_index;
iterator->this_arg = iterator->arg;
/* internally move on the size of this arg (using lower nybble from
- the table) */
+ the table) */
iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
-
+
/*
* check for insanity where we are given a bitmap that
* claims to have more arg content than the length of the
* radiotap section. We will normally end up equalling this
* max_length on the last arg, never exceeding it.
- */
+ */
if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > iterator->max_length)
- return -1;
+ return -1;
}
/* Now, move on to next bit / next entry */
}
}
else
- {
+ {
/* just try the next bit (while loop will move on) */
iterator->bitmap_shifter >>= 1;
}
if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
return 0;
- return 1;
+ return 1;
}
* @return number of bytes written to 'buf'
*/
static ssize_t
-linux_read (struct HardwareInfos *dev,
+linux_read (struct HardwareInfos *dev,
unsigned char *buf, size_t buf_size,
struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
{
return -1;
}
- memset (ri, 0, sizeof (*ri));
+ memset (ri, 0, sizeof (*ri));
switch (dev->arptype_in)
{
case ARPHRD_IEEE80211_PRISM:
if (PRISM_STATUS_OK == pv.status)
{
ri->ri_noise = pv.data;
- got_noise = 1;
+ /* got_noise = 1; */
}
break;
case PRISM_DID_RATE:
if (PRISM_STATUS_OK == pv.status)
{
ri->ri_power = pv.data;
- got_signal = 1;
+ /* got_signal = 1; */
}
break;
}
}
- }
+ }
if ( (n < 8) || (n >= caplen) )
return 0; /* invalid format */
}
if (!got_signal)
{
ri->ri_power = * ((int8_t*) iterator.this_arg);
- got_signal = 1;
+ got_signal = 1;
}
break;
case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
break;
} /* end of 'switch' */
} /* end of the 'while' loop */
- }
+ }
break;
case ARPHRD_IEEE80211:
n = 0; /* no header */
break;
+ case ARPHRD_ETHER:
+ {
+ if (sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
+ return 0; /* invalid */
+ memcpy (&buf[sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)],
+ tmpbuf + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame),
+ caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4 /* 4 byte FCS */);
+ return caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
+ }
default:
errno = ENOTSUP; /* unsupported format */
return -1;
ri->ri_channel = linux_get_channel (dev);
/* detect CRC32 at the end, even if the flag wasn't set and remove it */
- if ( (0 == fcs_removed) &&
- (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) )
+ if ( (0 == fcs_removed) &&
+ (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) )
{
/* NOTE: this heuristic can of course fail if there happens to
be a matching checksum at the end. Would be good to have
IFNAMSIZ, dev->iface, strerror (errno));
return 1;
}
+ if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
+ (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
+ (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
+ (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) )
+ {
+ fprintf (stderr, "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
+ IFNAMSIZ, dev->iface,
+ ifr.ifr_hwaddr.sa_family);
+ return 1;
+ }
/* lookup iw mode */
memset (&wrq, 0, sizeof (struct iwreq));
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))
+ if ( (wrq.u.mode != IW_MODE_MONITOR) &&
+ (wrq.u.mode != IW_MODE_ADHOC) )
{
- fprintf (stderr, "Error: interface `%.*s' is not in monitor mode\n",
- IFNAMSIZ, dev->iface);
+ fprintf (stderr, "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
+ IFNAMSIZ, dev->iface,
+ wrq.u.mode);
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) &&
+ if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
+ (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
(ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
(ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
{
setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
sizeof (mr)))
{
- fprintf (stderr,
+ fprintf (stderr,
"Failed to enable promiscuous mode on interface `%.*s'\n",
- IFNAMSIZ,
+ IFNAMSIZ,
dev->iface);
return 1;
}
struct stat sbuf;
int ret;
- ret = snprintf (strbuf, sizeof (strbuf),
+ 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",
+ fprintf (stderr,
+ "Did not find 802.11 interface `%s'. Exiting.\n",
iface);
exit (1);
}
mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
const struct HardwareInfos *dev)
{
+ static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
+
+ if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
+ (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
+ return 0; /* some drivers set no Macs, then assume it is all for us! */
+
if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
return 1; /* not a GNUnet ad-hoc package */
if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
size_t sendsize;
struct RadiotapTransmissionHeader rtheader;
+ struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
sendsize = ntohs (hdr->size);
if ( (sendsize <
sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
- (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
+ (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
{
fprintf (stderr, "Received malformed message\n");
exit (1);
exit (1);
}
header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
- rtheader.header.it_version = 0;
- rtheader.header.it_pad = 0;
- rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
- rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK);
- rtheader.rate = header->rate;
- rtheader.pad1 = 0;
- rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
- memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
- memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize);
- wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
-
- /* payload contains MAC address, but we don't trust it, so we'll
- * overwrite it with OUR MAC address to prevent mischief */
- mac_set (wlanheader, dev);
- write_pout.size = sendsize + sizeof (rtheader);
+ switch (dev->arptype_in)
+ {
+ case ARPHRD_IEEE80211_PRISM:
+ case ARPHRD_IEEE80211_FULL:
+ case ARPHRD_IEEE80211:
+ rtheader.header.it_version = 0;
+ rtheader.header.it_pad = 0;
+ rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
+ rtheader.header.it_present = GNUNET_htole16 (IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK);
+ rtheader.rate = header->rate;
+ rtheader.pad1 = 0;
+ rtheader.txflags = GNUNET_htole16 (IEEE80211_RADIOTAP_F_TX_NOACK | IEEE80211_RADIOTAP_F_TX_NOSEQ);
+ memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
+ memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize);
+ wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
+
+ /* payload contains MAC address, but we don't trust it, so we'll
+ * overwrite it with OUR MAC address to prevent mischief */
+ mac_set (wlanheader, dev);
+ write_pout.size = sendsize + sizeof (rtheader);
+ break;
+ case ARPHRD_ETHER:
+ etheader.dst = header->frame.addr1;
+ /* etheader.src = header->frame.addr2; --- untrusted input */
+ etheader.src = dev->pl_mac;
+ etheader.type = htons (ETH_P_IP);
+ memcpy (write_pout.buf, ðeader, sizeof (etheader));
+ memcpy (&write_pout.buf[sizeof (etheader)], &header[1], sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
+ write_pout.size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame) + sizeof (etheader);
+ break;
+ default:
+ fprintf (stderr,
+ "Unsupported ARPTYPE!\n");
+ break;
+ }
}
int stdin_open;
struct MessageStreamTokenizer *stdin_mst;
int raw_eno;
+ uid_t uid;
/* assert privs so we can modify the firewall rules! */
uid = getuid ();
return 254;
}
#else
- if (0 != seteuid (0))
+ if (0 != seteuid (0))
{
fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
return 254;
memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
memcpy (write_std.buf, &macmsg, sizeof (macmsg));
write_std.size = sizeof (macmsg);
- }
+ }
- stdin_mst = mst_create (&stdin_send_hw, &dev);
+ stdin_mst = mst_create (&stdin_send_hw, &dev);
stdin_open = 1;
while (1)
{
if (FD_ISSET (dev.fd_raw, &wfds))
{
ssize_t ret =
- write (dev.fd_raw, write_pout.buf + write_std.pos,
+ write (dev.fd_raw, write_pout.buf + write_std.pos,
write_pout.size - write_pout.pos);
if (0 > ret)
{
if (FD_ISSET (STDIN_FILENO, &rfds))
{
- ssize_t ret =
+ ssize_t ret =
read (STDIN_FILENO, readbuf, sizeof (readbuf));
if (0 > ret)
{
rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
ret =
linux_read (&dev, (unsigned char *) &rrm->frame,
- sizeof (write_std.buf)
- - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
+ sizeof (write_std.buf)
+ - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
rrm);
if (0 > ret)
{
}
if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
{
- write_std.size = ret
- + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+ write_std.size = ret
+ + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
- sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
rrm->header.size = htons (write_std.size);
rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);