+/**
+ * function to set the wlan header to make attacks more difficult
+ * @param u8aIeeeHeader pointer to the header of the packet
+ * @param dev pointer to the Hardware_Infos struct
+ */
+static void
+mac_set (struct ieee80211_frame *u8aIeeeHeader,
+ const struct Hardware_Infos *dev)
+{
+ u8aIeeeHeader->i_fc[0] = 0x08;
+ u8aIeeeHeader->i_fc[1] = 0x00;
+ 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)
+{
+ 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)
+{
+ 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
+ };
+
+ /*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
+ * }; */
+
+ u8aRadiotap[8] = (rate / 500000);
+ 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
+ };
+ if (0 == first)
+ {
+ 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);
+
+}
+#endif
+
+
+/**
+ * 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;
+ char readbuf[MAXLINE];
+ struct sendbuf write_std;
+ ssize_t ret;
+ int maxfd;
+ fd_set rfds;
+ fd_set wfds;
+ int retval;
+ 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);