2 This file is part of GNUnet.
3 (C) 2010 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-wlan.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
30 #include "gnunet-transport-wlan-helper.h"
31 #include "ieee80211_radiotap.h"
35 //#include "radiotap.h"
38 static const char macbc[] = "13223344";
41 char mac[] = "13223355";
43 /* wifi bitrate to use in 500kHz units */
45 static const u8 u8aRatesToUse[] = {
60 /* Penumbra IEEE80211 header */
61 static const u8 u8aIeeeHeader[] = {
62 0x08, 0x01, 0x00, 0x00,
63 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
64 0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
65 0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
69 /* this is the template radiotap header we send packets out with */
71 static const u8 u8aRadiotapHeader[] = {
73 0x00, 0x00, // <-- radiotap version
74 0x19, 0x00, // <- radiotap header length
75 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
77 0x00, // <-- flags (Offset +0x10)
78 0x6c, // <-- rate (0ffset +0x11)
79 0x71, 0x09, 0xc0, 0x00, // <-- channel
80 0xde, // <-- antsignal
85 #define OFFSET_FLAGS 0x10
86 #define OFFSET_RATE 0x11
88 // this is where we store a summary of the
89 // information from the radiotap header
97 } __attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
100 Dump(u8 * pu8, int nLength)
102 char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
103 unsigned char baaLast[2][16];
104 uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
109 for (n = 0; n < nLength; n++) {
110 baaLast[(nLine&1)^1][n&0xf] = pu8[n];
111 if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
114 szChar[n&0xf] = pu8[n];
115 szChar[(n&0xf)+1] = '\0';
116 nPos += sprintf(&sz[nPos], "%02X ",
117 baaLast[(nLine&1)^1][n&0xf]);
120 if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) {
124 buf += sprintf(buf, "(repeated %d times)\n",
126 buf += sprintf(buf, "%04x: %s %s\n",
132 nPos = 0; nStart = n+1; nLine++;
133 fFirst = 0; sz[0] = '\0'; szChar[0] = '\0';
136 buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
138 buf += sprintf(buf, "%04x: %s", nStart, sz);
142 buf += sprintf(buf, " ");
146 buf += sprintf(buf, "%s\n", szChar);
155 "Usage: wlan-hwd [options] <interface>\n\nOptions\n"
156 "-f/--fcs Mark as having FCS (CRC) already\n"
157 " (pkt ends with 4 x sacrificial - chars)\n"
159 " echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
160 " iwconfig mon0 mode monitor\n"
161 " ifconfig mon0 up\n"
162 " wlan-hwd mon0 Spam down mon0 with\n"
163 " radiotap header first\n"
168 int flagHelp = 0, flagMarkWithFCS = 0;
175 * Copyright 2007 Andy Green <andy@warmcat.com>
179 * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
180 * @iterator: radiotap_iterator to initialize
181 * @radiotap_header: radiotap header to parse
182 * @max_length: total length we can parse into (eg, whole packet length)
184 * Returns: 0 or a negative error code if there is a problem.
186 * This function initializes an opaque iterator struct which can then
187 * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
188 * argument which is present in the header. It knows about extended
189 * present headers and handles them.
192 * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
193 * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
194 * checking for a good 0 return code. Then loop calling
195 * __ieee80211_radiotap_iterator_next()... it returns either 0,
196 * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
197 * The iterator's @this_arg member points to the start of the argument
198 * associated with the current argument index that is present, which can be
199 * found in the iterator's @this_arg_index member. This arg index corresponds
200 * to the IEEE80211_RADIOTAP_... defines.
202 * Radiotap header length:
203 * You can find the CPU-endian total radiotap header length in
204 * iterator->max_length after executing ieee80211_radiotap_iterator_init()
208 * See Documentation/networking/radiotap-headers.txt
211 int ieee80211_radiotap_iterator_init(
212 struct ieee80211_radiotap_iterator *iterator,
213 struct ieee80211_radiotap_header *radiotap_header,
216 /* Linux only supports version 0 radiotap format */
217 if (radiotap_header->it_version)
220 /* sanity check for allowed length and radiotap length field */
221 if (max_length < le16_to_cpu(radiotap_header->it_len))
224 iterator->rtheader = radiotap_header;
225 iterator->max_length = le16_to_cpu(radiotap_header->it_len);
226 iterator->arg_index = 0;
227 iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present);
228 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
229 iterator->this_arg = 0;
231 /* find payload start allowing for extended bitmap(s) */
233 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
234 while (le32_to_cpu(*((u32 *)iterator->arg)) &
235 (1<<IEEE80211_RADIOTAP_EXT)) {
236 iterator->arg += sizeof(u32);
239 * check for insanity where the present bitmaps
240 * keep claiming to extend up to or even beyond the
241 * stated radiotap header length
244 if (((ulong)iterator->arg -
245 (ulong)iterator->rtheader) > iterator->max_length)
249 iterator->arg += sizeof(u32);
252 * no need to check again for blowing past stated radiotap
253 * header length, because ieee80211_radiotap_iterator_next
254 * checks it before it is dereferenced
258 /* we are all initialized happily */
265 * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
266 * @iterator: radiotap_iterator to move to next arg (if any)
268 * Returns: 0 if there is an argument to handle,
269 * -ENOENT if there are no more args or -EINVAL
270 * if there is something else wrong.
272 * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
273 * in @this_arg_index and sets @this_arg to point to the
274 * payload for the field. It takes care of alignment handling and extended
275 * present fields. @this_arg can be changed by the caller (eg,
276 * incremented to move inside a compound argument like
277 * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
278 * little-endian format whatever the endianess of your CPU.
281 int ieee80211_radiotap_iterator_next(
282 struct ieee80211_radiotap_iterator *iterator)
286 * small length lookup table for all radiotap types we heard of
287 * starting from b0 in the bitmap, so we can walk the payload
288 * area of the radiotap header
290 * There is a requirement to pad args, so that args
291 * of a given length must begin at a boundary of that length
292 * -- but note that compound args are allowed (eg, 2 x u16
293 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
294 * a reliable indicator of alignment requirement.
296 * upper nybble: content alignment for arg
297 * lower nybble: content length for arg
300 static const u8 rt_sizes[] = {
301 [IEEE80211_RADIOTAP_TSFT] = 0x88,
302 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
303 [IEEE80211_RADIOTAP_RATE] = 0x11,
304 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
305 [IEEE80211_RADIOTAP_FHSS] = 0x22,
306 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
307 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
308 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
309 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
310 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
311 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
312 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
313 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
314 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11
316 * add more here as they are defined in
317 * include/net/ieee80211_radiotap.h
322 * for every radiotap entry we can at
323 * least skip (by knowing the length)...
326 while (iterator->arg_index < sizeof(rt_sizes)) {
330 if (!(iterator->bitmap_shifter & 1))
331 goto next_entry; /* arg not present */
334 * arg is present, account for alignment padding
335 * 8-bit args can be at any alignment
336 * 16-bit args must start on 16-bit boundary
337 * 32-bit args must start on 32-bit boundary
338 * 64-bit args must start on 64-bit boundary
340 * note that total arg size can differ from alignment of
341 * elements inside arg, so we use upper nybble of length
342 * table to base alignment on
344 * also note: these alignments are ** relative to the
345 * start of the radiotap header **. There is no guarantee
346 * that the radiotap header itself is aligned on any
350 pad = (((ulong)iterator->arg) -
351 ((ulong)iterator->rtheader)) &
352 ((rt_sizes[iterator->arg_index] >> 4) - 1);
355 iterator->arg_index +=
356 (rt_sizes[iterator->arg_index] >> 4) - pad;
359 * this is what we will return to user, but we need to
360 * move on first so next call has something fresh to test
362 iterator->this_arg_index = iterator->arg_index;
363 iterator->this_arg = iterator->arg;
366 /* internally move on the size of this arg */
367 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
370 * check for insanity where we are given a bitmap that
371 * claims to have more arg content than the length of the
372 * radiotap section. We will normally end up equalling this
373 * max_length on the last arg, never exceeding it.
376 if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
377 iterator->max_length)
381 iterator->arg_index++;
382 if (unlikely((iterator->arg_index & 31) == 0)) {
383 /* completed current u32 bitmap */
384 if (iterator->bitmap_shifter & 1) {
385 /* b31 was set, there is more */
386 /* move to next u32 bitmap */
387 iterator->bitmap_shifter =
388 le32_to_cpu(*iterator->next_bitmap);
389 iterator->next_bitmap++;
391 /* no more bitmaps: end */
392 iterator->arg_index = sizeof(rt_sizes);
394 } else { /* just try the next bit */
395 iterator->bitmap_shifter >>= 1;
398 /* if we found a valid arg earlier, return it now */
403 /* we don't know how to handle any more args, we're done */
410 main(int argc, char *argv[])
412 u8 u8aSendBuffer[500];
413 char szErrbuf[PCAP_ERRBUF_SIZE];
414 int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
415 int nOrdinal = 0, r, nDelay = 100000;
416 int nRateIndex = 0, retval, bytes;
417 pcap_t *ppcap = NULL;
418 struct bpf_program bpfprogram;
419 char * szProgram = "", fBrokenSocket = 0;
421 char szHostname[PATH_MAX];
423 if (gethostname(szHostname, sizeof (szHostname) - 1)) {
424 perror("unable to get hostname");
426 szHostname[sizeof (szHostname) - 1] = '\0';
429 printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
433 static const struct option optiona[] = {
434 { "delay", required_argument, NULL, 'd' },
435 { "fcs", no_argument, &flagMarkWithFCS, 1 },
436 { "help", no_argument, &flagHelp, 1 },
437 { "verbose", no_argument, &flagVerbose, 1},
440 int c = getopt_long(argc, argv, "d:hf",
441 optiona, &nOptionIndex);
446 case 0: // long option
453 nDelay = atoi(optarg);
456 case 'f': // mark as FCS attached
460 case 'v': //Verbose / readable output to cout
465 printf("unknown switch %c\n", c);
475 // open the interface in pcap
478 ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
480 printf("Unable to open interface %s in pcap: %s\n",
481 argv[optind], szErrbuf);
485 //get mac from interface
490 sock=socket(PF_INET, SOCK_STREAM, 0);
492 perror("can not open socket\n");
496 if (-1==ioctl(sock, SIOCGIFHWADDR, &ifr)) {
497 perror("ioctl(SIOCGIFHWADDR) ");
500 for (j=0, k=0; j<6; j++) {
501 k+=snprintf(mac+k, sizeof(mac)-k-1, j ? ":%02X" : "%02X",
502 (int)(unsigned int)(unsigned char)ifr.ifr_hwaddr.sa_data[j]);
504 mac[sizeof(mac)-1]='\0';
508 nLinkEncap = pcap_datalink(ppcap);
509 nCaptureHeaderLength = 0;
511 switch (nLinkEncap) {
513 case DLT_PRISM_HEADER:
514 printf("DLT_PRISM_HEADER Encap\n");
515 nCaptureHeaderLength = 0x40;
516 n80211HeaderLength = 0x20; // ieee80211 comes after this
517 szProgram = "radio[0x4a:4]==0x13223344";
520 case DLT_IEEE802_11_RADIO:
521 printf("DLT_IEEE802_11_RADIO Encap\n");
522 nCaptureHeaderLength = 0x40;
523 n80211HeaderLength = 0x18; // ieee80211 comes after this
524 szProgram = "ether[0x0a:4]==0x13223344";
528 printf("!!! unknown encapsulation on %s !\n", argv[1]);
533 if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
535 puts(pcap_geterr(ppcap));
538 if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
540 puts(pcap_geterr(ppcap));
542 printf("RX Filter applied\n");
544 pcap_freecode(&bpfprogram);
547 pcap_setnonblock(ppcap, 1, szErrbuf);
549 printf(" (delay between packets %dus)\n", nDelay);
551 memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
553 while (!fBrokenSocket) {
554 u8 * pu8 = u8aSendBuffer;
555 struct pcap_pkthdr * ppcapPacketHeader = NULL;
556 struct ieee80211_radiotap_iterator rti;
557 PENUMBRA_RADIOTAP_DATA prd;
558 u8 * pu8Payload = u8aSendBuffer;
563 retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
564 (const u_char**)&pu8Payload);
574 u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
577 Dump(pu8Payload, u16HeaderLen);
579 if (ppcapPacketHeader->len <
580 (u16HeaderLen + n80211HeaderLength))
583 bytes = ppcapPacketHeader->len -
584 (u16HeaderLen + n80211HeaderLength);
588 if (ieee80211_radiotap_iterator_init(&rti,
589 (struct ieee80211_radiotap_header *)pu8Payload,
593 while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
595 switch (rti.this_arg_index) {
596 case IEEE80211_RADIOTAP_RATE:
597 prd.m_nRate = (*rti.this_arg);
600 case IEEE80211_RADIOTAP_CHANNEL:
602 le16_to_cpu(*((u16 *)rti.this_arg));
603 prd.m_nChannelFlags =
604 le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
607 case IEEE80211_RADIOTAP_ANTENNA:
608 prd.m_nAntenna = (*rti.this_arg) + 1;
611 case IEEE80211_RADIOTAP_FLAGS:
612 prd.m_nRadiotapFlags = *rti.this_arg;
618 pu8Payload += u16HeaderLen + n80211HeaderLength;
620 if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
623 printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
624 "Ant: %d, Flags: 0x%X\n",
625 prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
626 prd.m_nChannel / 1000,
627 prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
629 prd.m_nRadiotapFlags);
631 Dump(pu8Payload, bytes);
637 memcpy(u8aSendBuffer, u8aRadiotapHeader,
638 sizeof (u8aRadiotapHeader));
640 pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
641 nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
642 if (nRateIndex >= sizeof (u8aRatesToUse))
644 pu8 += sizeof (u8aRadiotapHeader);
646 memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
647 pu8 += sizeof (u8aIeeeHeader);
649 pu8 += sprintf((char *)u8aSendBuffer,
652 "#%05d -- :-D --%s ----",
653 nRate/2, nOrdinal++, szHostname);
654 r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
655 if (r != (pu8-u8aSendBuffer)) {
656 perror("Trouble injecting packet");