GNUnet  0.10.x
gnunet-helper-transport-wlan.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4  Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5  Copyright Copyright (C) 2009 Thomas d'Otreppe
6 
7  GNUnet is free software: you can redistribute it and/or modify it
8  under the terms of the GNU Affero General Public License as published
9  by the Free Software Foundation, either version 3 of the License,
10  or (at your option) any later version.
11 
12  GNUnet is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Affero General Public License for more details.
16 
17  You should have received a copy of the GNU Affero General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20  SPDX-License-Identifier: AGPL3.0-or-later
21 */
68 /*-
69  * we use our local copy of ieee80211_radiotap.h
70  *
71  * - since we can't support extensions we don't understand
72  * - since linux does not include it in userspace headers
73  *
74  * Portions of this code were taken from the ieee80211_radiotap.h header,
75  * which is
76  *
77  * Copyright (c) 2003, 2004 David Young. All rights reserved.
78  *
79  * Redistribution and use in source and binary forms, with or without
80  * modification, are permitted provided that the following conditions
81  * are met:
82  * 1. Redistributions of source code must retain the above copyright
83  * notice, this list of conditions and the following disclaimer.
84  * 2. Redistributions in binary form must reproduce the above copyright
85  * notice, this list of conditions and the following disclaimer in the
86  * documentation and/or other materials provided with the distribution.
87  * 3. The name of David Young may not be used to endorse or promote
88  * products derived from this software without specific prior
89  * written permission.
90  *
91  * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
92  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
93  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
94  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
95  * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
96  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
97  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
100  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
102  * OF SUCH DAMAGE.
103  */
104 
105 /*
106  * Modifications to fit into the linux IEEE 802.11 stack,
107  * Mike Kershaw (dragorn@kismetwireless.net)
108  */
109 /*
110  * parts taken from aircrack-ng, parts changend.
111  */
112 #include "gnunet_config.h"
113 #define SOCKTYPE int
114 #define FDTYPE int
115 #include <sys/socket.h>
116 #include <sys/ioctl.h>
117 #include <sys/types.h>
118 #include <unistd.h>
119 #include <sys/wait.h>
120 #include <sys/time.h>
121 #include <sys/stat.h>
122 #include <netpacket/packet.h>
123 #include <linux/if_ether.h>
124 #include <linux/if.h>
125 #include <linux/wireless.h>
126 #include <netinet/in.h>
127 #include <linux/if_tun.h>
128 #include <stdio.h>
129 #include <stdlib.h>
130 #include <string.h>
131 #include <stdarg.h>
132 #include <fcntl.h>
133 #include <errno.h>
134 #include <dirent.h>
135 #include <sys/param.h>
136 #include <unistd.h>
137 #include <stdint.h>
138 
139 #include "gnunet_protocols.h"
140 #include "plugin_transport_wlan.h"
141 
147 #define ARPHRD_ETHER 1
148 
149 
155 #define ARPHRD_IEEE80211 801
156 
157 
162 #define ARPHRD_IEEE80211_PRISM 802
163 
169 #define ARPHRD_IEEE80211_FULL 803
170 
171 
176 #define MAXLINE 4096
177 
178 
179 
180 /* ********* structure of messages of type ARPHRD_IEEE80211_PRISM *********** */
181 
186 #define PRISM_DEVICE_NAME_LENGTH 16
187 
191 #define PRISM_MSGCODE_MONITOR 0x0041
192 
198 #define PRISM_DID_MACTIME 0x2041
199 
203 #define PRISM_DID_CHANNEL 0x3041
204 
210 #define PRISM_DID_SIGNAL 0x6041
211 
215 #define PRISM_DID_NOISE 0x7041
216 
220 #define PRISM_DID_RATE 0x8041
221 
222 
226 #define PRISM_STATUS_OK 0
227 
231 #define PRISM_STATUS_NO_VALUE 1
232 
233 
238 {
243  uint32_t did;
244 
248  uint16_t status;
249 
255  uint16_t len;
256 
260  uint32_t data;
261 
262 } __attribute__ ((packed));
263 
264 
269 {
273  uint32_t msgcode;
274 
278  uint32_t msglen;
279 
284 
285  /* followed by 'struct PrismValue's. Documentation suggests that these
286  are typically the hosttime, mactime, channel, rssi, sq, signal, noise,
287  rate, istx and frmlen values, but documentation is sparse. So we
288  will use the 'did' fields to find out what we actually got. */
289 
290 } __attribute__ ((packed));
291 
292 
293 /* ****** end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */
294 
295 /* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */
296 
309 {
310 
319 
327 
334 
348 
357 
366 
376 
385 
394 
404 
412 
420 
428 
435 
442 
449 
456 
462 };
463 
468 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT)
469 
470 
471 
480 #define IEEE80211_RADIOTAP_F_CFP 0x01
481 
490 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
491 
500 #define IEEE80211_RADIOTAP_F_WEP 0x04
501 
510 #define IEEE80211_RADIOTAP_F_FRAG 0x08
511 
520 #define IEEE80211_RADIOTAP_F_FCS 0x10
521 
531 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20
532 
533 
538 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
539 
544 #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
545 
550 #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
551 
556 #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
557 
562 #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008
563 
568 #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010
569 
570 
586 {
591  uint8_t it_version;
592 
596  uint8_t it_pad;
597 
602  uint16_t it_len;
603 
609  uint32_t it_present;
610 };
611 
612 
618 {
619 
624  struct Ieee80211RadiotapHeader header;
625 
629  uint8_t rate;
630 
637  uint8_t pad1;
638 
642  uint16_t txflags;
643 
644 };
645 
651 #define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_TX_FLAGS))
652 
653 
654 
660 {
665 
669  const uint8_t *this_arg;
670 
674  const uint8_t *arg;
675 
679  const uint32_t *next_bitmap;
680 
684  size_t max_length;
685 
690  uint32_t bitmap_shifter;
691 
695  unsigned int this_arg_index;
696 
700  unsigned int arg_index;
701 
702 };
703 
704 
705 /* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
706 
707 /* ************************** our globals ******************************* */
708 
713 struct HardwareInfos
714 {
715 
719  int fd_raw;
720 
726 
730  char iface[IFNAMSIZ];
731 
735  struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
736 };
737 
738 
742 struct SendBuffer
743 {
748  size_t size;
749 
754  size_t pos;
755 
760  char buf[MAXLINE * 2];
761 };
762 
763 
767 static struct SendBuffer write_pout;
768 
772 static struct SendBuffer write_std;
773 
774 
775 
776 /* *********** specialized version of server_mst.c begins here ********** */
777 
782 #define ALIGN_FACTOR 8
783 
787 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
788 
789 
797 typedef void (*MessageTokenizerCallback) (void *cls,
798  const struct
800  message);
801 
806 {
807 
812 
816  void *cb_cls;
817 
821  size_t curr_buf;
822 
826  size_t off;
827 
831  size_t pos;
832 
836  struct GNUNET_MessageHeader *hdr;
837 
838 };
839 
840 
848 static struct MessageStreamTokenizer *
850  void *cb_cls)
851 {
852  struct MessageStreamTokenizer *ret;
853 
854  ret = malloc (sizeof (struct MessageStreamTokenizer));
855  if (NULL == ret)
856  {
857  fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
858  exit (1);
859  }
860  ret->hdr = malloc (MIN_BUFFER_SIZE);
861  if (NULL == ret->hdr)
862  {
863  fprintf (stderr, "Failed to allocate buffer for alignment\n");
864  exit (1);
865  }
866  ret->curr_buf = MIN_BUFFER_SIZE;
867  ret->cb = cb;
868  ret->cb_cls = cb_cls;
869  return ret;
870 }
871 
872 
883 static int
885  const char *buf, size_t size)
886 {
887  const struct GNUNET_MessageHeader *hdr;
888  size_t delta;
889  uint16_t want;
890  char *ibuf;
891  int need_align;
892  unsigned long offset;
893  int ret;
894 
895  ret = GNUNET_OK;
896  ibuf = (char *) mst->hdr;
897  while (mst->pos > 0)
898  {
899 do_align:
900  if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
901  (0 != (mst->off % ALIGN_FACTOR)))
902  {
903  /* need to align or need more space */
904  mst->pos -= mst->off;
905  memmove (ibuf, &ibuf[mst->off], mst->pos);
906  mst->off = 0;
907  }
908  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
909  {
910  delta =
911  GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
912  (mst->pos - mst->off), size);
913  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
914  mst->pos += delta;
915  buf += delta;
916  size -= delta;
917  }
918  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
919  {
920  return GNUNET_OK;
921  }
922  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
923  want = ntohs (hdr->size);
924  if (want < sizeof (struct GNUNET_MessageHeader))
925  {
926  fprintf (stderr,
927  "Received invalid message from stdin\n");
928  exit (1);
929  }
930  if (mst->curr_buf - mst->off < want)
931  {
932  /* need more space */
933  mst->pos -= mst->off;
934  memmove (ibuf, &ibuf[mst->off], mst->pos);
935  mst->off = 0;
936  }
937  if (want > mst->curr_buf)
938  {
939  mst->hdr = realloc (mst->hdr, want);
940  if (NULL == mst->hdr)
941  {
942  fprintf (stderr, "Failed to allocate buffer for alignment\n");
943  exit (1);
944  }
945  ibuf = (char *) mst->hdr;
946  mst->curr_buf = want;
947  }
948  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
949  if (mst->pos - mst->off < want)
950  {
951  delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
952  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
953  mst->pos += delta;
954  buf += delta;
955  size -= delta;
956  }
957  if (mst->pos - mst->off < want)
958  {
959  return GNUNET_OK;
960  }
961  mst->cb (mst->cb_cls, hdr);
962  mst->off += want;
963  if (mst->off == mst->pos)
964  {
965  /* reset to beginning of buffer, it's free right now! */
966  mst->off = 0;
967  mst->pos = 0;
968  }
969  }
970  while (size > 0)
971  {
972  if (size < sizeof (struct GNUNET_MessageHeader))
973  break;
974  offset = (unsigned long) buf;
975  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
976  if (GNUNET_NO == need_align)
977  {
978  /* can try to do zero-copy and process directly from original buffer */
979  hdr = (const struct GNUNET_MessageHeader *) buf;
980  want = ntohs (hdr->size);
981  if (want < sizeof (struct GNUNET_MessageHeader))
982  {
983  fprintf (stderr,
984  "Received invalid message from stdin\n");
985  exit (1);
986  }
987  if (size < want)
988  break; /* or not, buffer incomplete, so copy to private buffer... */
989  mst->cb (mst->cb_cls, hdr);
990  buf += want;
991  size -= want;
992  }
993  else
994  {
995  /* need to copy to private buffer to align;
996  * yes, we go a bit more spagetti than usual here */
997  goto do_align;
998  }
999  }
1000  if (size > 0)
1001  {
1002  if (size + mst->pos > mst->curr_buf)
1003  {
1004  mst->hdr = realloc (mst->hdr, size + mst->pos);
1005  if (NULL == mst->hdr)
1006  {
1007  fprintf (stderr, "Failed to allocate buffer for alignment\n");
1008  exit (1);
1009  }
1010  ibuf = (char *) mst->hdr;
1011  mst->curr_buf = size + mst->pos;
1012  }
1013  if (mst->pos + size > mst->curr_buf)
1014  {
1015  fprintf (stderr,
1016  "Assertion failed\n");
1017  exit (1);
1018  }
1019  GNUNET_memcpy (&ibuf[mst->pos], buf, size);
1020  mst->pos += size;
1021  }
1022  return ret;
1023 }
1024 
1025 
1031 static void
1033 {
1034  free (mst->hdr);
1035  free (mst);
1036 }
1037 
1038 /* ***************** end of server_mst.c clone ***************** **/
1039 
1040 
1041 /* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */
1042 
1060 static int
1062  const struct Ieee80211RadiotapHeader *radiotap_header,
1063  size_t max_length)
1064 {
1065  if ( (iterator == NULL) ||
1066  (radiotap_header == NULL) )
1067  return -1;
1068 
1069  /* Linux only supports version 0 radiotap format */
1070  if (0 != radiotap_header->it_version)
1071  return -1;
1072 
1073  /* sanity check for allowed length and radiotap length field */
1074  if ( (max_length < sizeof (struct Ieee80211RadiotapHeader)) ||
1075  (max_length < (GNUNET_le16toh (radiotap_header->it_len))) )
1076  return -1;
1077 
1078  memset (iterator, 0, sizeof (struct Ieee80211RadiotapHeaderIterator));
1079  iterator->rtheader = radiotap_header;
1080  iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
1081  iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
1082  iterator->arg = ((uint8_t *) radiotap_header) + sizeof (struct Ieee80211RadiotapHeader);
1083 
1084  /* find payload start allowing for extended bitmap(s) */
1086  {
1087  while (GNUNET_le32toh (*((uint32_t *) iterator->arg)) & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
1088  {
1089  iterator->arg += sizeof (uint32_t);
1090  /*
1091  * check for insanity where the present bitmaps
1092  * keep claiming to extend up to or even beyond the
1093  * stated radiotap header length
1094  */
1095  if (iterator->arg - ((uint8_t*) iterator->rtheader) > iterator->max_length)
1096  return -1;
1097  }
1098  iterator->arg += sizeof (uint32_t);
1099  /*
1100  * no need to check again for blowing past stated radiotap
1101  * header length, becuase ieee80211_radiotap_iterator_next
1102  * checks it before it is dereferenced
1103  */
1104  }
1105  /* we are all initialized happily */
1106  return 0;
1107 }
1108 
1109 
1122 static int
1124 {
1125  /*
1126  * small length lookup table for all radiotap types we heard of
1127  * starting from b0 in the bitmap, so we can walk the payload
1128  * area of the radiotap header
1129  *
1130  * There is a requirement to pad args, so that args
1131  * of a given length must begin at a boundary of that length
1132  * -- but note that compound args are allowed (eg, 2 x uint16_t
1133  * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
1134  * a reliable indicator of alignment requirement.
1135  *
1136  * upper nybble: content alignment for arg
1137  * lower nybble: content length for arg
1138  */
1139 
1140  static const uint8_t rt_sizes[] = {
1141  [IEEE80211_RADIOTAP_TSFT] = 0x88,
1142  [IEEE80211_RADIOTAP_FLAGS] = 0x11,
1143  [IEEE80211_RADIOTAP_RATE] = 0x11,
1144  [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
1145  [IEEE80211_RADIOTAP_FHSS] = 0x22,
1152  [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
1155  [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
1156  [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
1159  /*
1160  * add more here as they are defined in
1161  * include/net/ieee80211_radiotap.h
1162  */
1163  };
1164 
1165  /*
1166  * for every radiotap entry we can at
1167  * least skip (by knowing the length)...
1168  */
1169  while (iterator->arg_index < sizeof (rt_sizes))
1170  {
1171  int hit = (0 != (iterator->bitmap_shifter & 1));
1172 
1173  if (hit)
1174  {
1175  unsigned int wanted_alignment;
1176  unsigned int unalignment;
1177  /*
1178  * arg is present, account for alignment padding
1179  * 8-bit args can be at any alignment
1180  * 16-bit args must start on 16-bit boundary
1181  * 32-bit args must start on 32-bit boundary
1182  * 64-bit args must start on 64-bit boundary
1183  *
1184  * note that total arg size can differ from alignment of
1185  * elements inside arg, so we use upper nybble of length table
1186  * to base alignment on. First, 'wanted_alignment' is set to be
1187  * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit
1188  * arguments. Then, we calculate the 'unalignment' (how many
1189  * bytes we are over by taking the difference of 'arg' and the
1190  * overall starting point modulo the desired alignment. As
1191  * desired alignments are powers of two, we can do modulo with
1192  * binary "&" (and also avoid the possibility of a division by
1193  * zero if the 'rt_sizes' table contains bogus entries).
1194  *
1195  * also note: these alignments are relative to the start of the
1196  * radiotap header. There is no guarantee that the radiotap
1197  * header itself is aligned on any kind of boundary, thus we
1198  * need to really look at the delta here.
1199  */
1200  wanted_alignment = rt_sizes[iterator->arg_index] >> 4;
1201  unalignment = (((void *) iterator->arg) - ((void *) iterator->rtheader)) & (wanted_alignment - 1);
1202  if (0 != unalignment)
1203  {
1204  /* need padding (by 'wanted_alignment - unalignment') */
1205  iterator->arg_index += wanted_alignment - unalignment;
1206  }
1207 
1208  /*
1209  * this is what we will return to user, but we need to
1210  * move on first so next call has something fresh to test
1211  */
1212  iterator->this_arg_index = iterator->arg_index;
1213  iterator->this_arg = iterator->arg;
1214 
1215  /* internally move on the size of this arg (using lower nybble from
1216  the table) */
1217  iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
1218 
1219  /*
1220  * check for insanity where we are given a bitmap that
1221  * claims to have more arg content than the length of the
1222  * radiotap section. We will normally end up equalling this
1223  * max_length on the last arg, never exceeding it.
1224  */
1225  if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) > iterator->max_length)
1226  return -1;
1227  }
1228 
1229  /* Now, move on to next bit / next entry */
1230  iterator->arg_index++;
1231 
1232  if (0 == (iterator->arg_index % 32))
1233  {
1234  /* completed current uint32_t bitmap */
1235  if (0 != (iterator->bitmap_shifter & 1))
1236  {
1237  /* bit 31 was set, there is more; move to next uint32_t bitmap */
1238  iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
1239  iterator->next_bitmap++;
1240  }
1241  else
1242  {
1243  /* no more bitmaps: end (by setting arg_index to high, unsupported value) */
1244  iterator->arg_index = sizeof (rt_sizes);
1245  }
1246  }
1247  else
1248  {
1249  /* just try the next bit (while loop will move on) */
1250  iterator->bitmap_shifter >>= 1;
1251  }
1252 
1253  /* if we found a valid arg earlier, return it now */
1254  if (hit)
1255  return iterator->this_arg_index;
1256  }
1257 
1258  /* we don't know how to handle any more args (or there are no more),
1259  so we're done (this is not an error) */
1260  return -1;
1261 }
1262 
1263 
1271 static unsigned long
1272 calc_crc_osdep (const unsigned char *buf, size_t len)
1273 {
1274  static const unsigned long int crc_tbl_osdep[256] = {
1275  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1276  0xE963A535, 0x9E6495A3,
1277  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
1278  0xE7B82D07, 0x90BF1D91,
1279  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
1280  0xF4D4B551, 0x83D385C7,
1281  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1282  0xFA0F3D63, 0x8D080DF5,
1283  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
1284  0xD20D85FD, 0xA50AB56B,
1285  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
1286  0xDCD60DCF, 0xABD13D59,
1287  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1288  0xCFBA9599, 0xB8BDA50F,
1289  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
1290  0xC1611DAB, 0xB6662D3D,
1291  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
1292  0x9FBFE4A5, 0xE8B8D433,
1293  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1294  0x91646C97, 0xE6635C01,
1295  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
1296  0x8208F4C1, 0xF50FC457,
1297  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
1298  0x8CD37CF3, 0xFBD44C65,
1299  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1300  0xA4D1C46D, 0xD3D6F4FB,
1301  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
1302  0xAA0A4C5F, 0xDD0D7CC9,
1303  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
1304  0xB966D409, 0xCE61E49F,
1305  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1306  0xB7BD5C3B, 0xC0BA6CAD,
1307  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1308  0x04DB2615, 0x73DC1683,
1309  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1310  0x0A00AE27, 0x7D079EB1,
1311  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1312  0x196C3671, 0x6E6B06E7,
1313  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1314  0x17B7BE43, 0x60B08ED5,
1315  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1316  0x3FB506DD, 0x48B2364B,
1317  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1318  0x316E8EEF, 0x4669BE79,
1319  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1320  0x220216B9, 0x5505262F,
1321  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1322  0x2CD99E8B, 0x5BDEAE1D,
1323  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1324  0x72076785, 0x05005713,
1325  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1326  0x7CDCEFB7, 0x0BDBDF21,
1327  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1328  0x6FB077E1, 0x18B74777,
1329  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1330  0x616BFFD3, 0x166CCF45,
1331  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1332  0x4969474D, 0x3E6E77DB,
1333  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1334  0x47B2CF7F, 0x30B5FFE9,
1335  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1336  0x54DE5729, 0x23D967BF,
1337  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1338  0x5A05DF1B, 0x2D02EF8D
1339  };
1340 
1341  unsigned long crc = 0xFFFFFFFF;
1342 
1343  for (; len > 0; len--, buf++)
1344  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1345  return (~crc);
1346 }
1347 
1348 
1357 static int
1358 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1359 {
1360  unsigned long crc;
1361 
1362  crc = calc_crc_osdep (buf, len);
1363  buf += len;
1364  if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1365  ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
1366  return 0;
1367  return 1;
1368 }
1369 
1370 
1371 /* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */
1372 
1373 
1374 /* ************beginning of code for reading packets from kernel ************** */
1375 
1382 static int
1383 get_channel_from_frequency (int32_t frequency)
1384 {
1385  if (frequency >= 2412 && frequency <= 2472)
1386  return (frequency - 2407) / 5;
1387  if (frequency == 2484)
1388  return 14;
1389  if (frequency >= 5000 && frequency <= 6100)
1390  return (frequency - 5000) / 5;
1391  return -1;
1392 }
1393 
1394 
1401 static int
1403 {
1404  struct iwreq wrq;
1405  int32_t frequency;
1406 
1407  memset (&wrq, 0, sizeof (struct iwreq));
1408  strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1409  if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq))
1410  return -1;
1411  frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */
1412  if (100000000 < frequency)
1413  frequency /= 100000;
1414  else if (1000000 < frequency)
1415  frequency /= 1000;
1416  if (1000 < frequency)
1417  return get_channel_from_frequency (frequency);
1418  return frequency;
1419 }
1420 
1421 
1433 static ssize_t
1435  unsigned char *buf, size_t buf_size,
1437 {
1438  unsigned char tmpbuf[buf_size];
1439  ssize_t caplen;
1440  size_t n;
1441  int got_signal = 0;
1442  int got_noise = 0;
1443  int got_channel = 0;
1444  int fcs_removed = 0;
1445 
1446  caplen = read (dev->fd_raw, tmpbuf, buf_size);
1447  if (0 > caplen)
1448  {
1449  if (EAGAIN == errno)
1450  return 0;
1451  fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1452  return -1;
1453  }
1454 
1455  memset (ri, 0, sizeof (*ri));
1456  switch (dev->arptype_in)
1457  {
1459  {
1460  const struct PrismHeader *ph;
1461 
1462  ph = (const struct PrismHeader*) tmpbuf;
1463  n = ph->msglen;
1464  if ( (n < 8) || (n >= caplen) )
1465  return 0; /* invalid format */
1466  if ( (PRISM_MSGCODE_MONITOR == ph->msgcode) &&
1467  (n >= sizeof (struct PrismHeader)) )
1468  {
1469  const char *pos;
1470  size_t left;
1471  struct PrismValue pv;
1472 
1473  left = n - sizeof (struct PrismHeader);
1474  pos = (const char *) &ph[1];
1475  while (left > sizeof (struct PrismValue))
1476  {
1477  left -= sizeof (struct PrismValue);
1478  GNUNET_memcpy (&pv, pos, sizeof (struct PrismValue));
1479  pos += sizeof (struct PrismValue);
1480 
1481  switch (pv.did)
1482  {
1483  case PRISM_DID_NOISE:
1484  if (PRISM_STATUS_OK == pv.status)
1485  {
1486  ri->ri_noise = pv.data;
1487  /* got_noise = 1; */
1488  }
1489  break;
1490  case PRISM_DID_RATE:
1491  if (PRISM_STATUS_OK == pv.status)
1492  ri->ri_rate = pv.data * 500000;
1493  break;
1494  case PRISM_DID_CHANNEL:
1495  if (PRISM_STATUS_OK == pv.status)
1496  {
1497  ri->ri_channel = pv.data;
1498  got_channel = 1;
1499  }
1500  break;
1501  case PRISM_DID_MACTIME:
1502  if (PRISM_STATUS_OK == pv.status)
1503  ri->ri_mactime = pv.data;
1504  break;
1505  case PRISM_DID_SIGNAL:
1506  if (PRISM_STATUS_OK == pv.status)
1507  {
1508  ri->ri_power = pv.data;
1509  /* got_signal = 1; */
1510  }
1511  break;
1512  }
1513  }
1514  }
1515  if ( (n < 8) || (n >= caplen) )
1516  return 0; /* invalid format */
1517  }
1518  break;
1519  case ARPHRD_IEEE80211_FULL:
1520  {
1521  struct Ieee80211RadiotapHeaderIterator iterator;
1522  struct Ieee80211RadiotapHeader *rthdr;
1523 
1524  memset (&iterator, 0, sizeof (iterator));
1525  rthdr = (struct Ieee80211RadiotapHeader *) tmpbuf;
1526  n = GNUNET_le16toh (rthdr->it_len);
1527  if ( (n < sizeof (struct Ieee80211RadiotapHeader)) || (n >= caplen))
1528  return 0; /* invalid 'it_len' */
1529  if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
1530  return 0;
1531  /* go through the radiotap arguments we have been given by the driver */
1532  while (0 <= ieee80211_radiotap_iterator_next (&iterator))
1533  {
1534  switch (iterator.this_arg_index)
1535  {
1537  ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1538  break;
1540  if (!got_signal)
1541  {
1542  ri->ri_power = * ((int8_t*) iterator.this_arg);
1543  got_signal = 1;
1544  }
1545  break;
1547  if (!got_signal)
1548  {
1549  ri->ri_power = * ((int8_t*) iterator.this_arg);
1550  got_signal = 1;
1551  }
1552  break;
1554  if (!got_noise)
1555  {
1556  ri->ri_noise = * ((int8_t*) iterator.this_arg);
1557  got_noise = 1;
1558  }
1559  break;
1561  if (!got_noise)
1562  {
1563  ri->ri_noise = * ((int8_t*) iterator.this_arg);
1564  got_noise = 1;
1565  }
1566  break;
1568  ri->ri_antenna = *iterator.this_arg;
1569  break;
1571  ri->ri_channel = *iterator.this_arg;
1572  got_channel = 1;
1573  break;
1575  ri->ri_rate = (*iterator.this_arg) * 500000;
1576  break;
1578  {
1579  uint8_t flags = *iterator.this_arg;
1580  /* is the CRC visible at the end? if so, remove */
1581  if (0 != (flags & IEEE80211_RADIOTAP_F_FCS))
1582  {
1583  fcs_removed = 1;
1584  caplen -= sizeof (uint32_t);
1585  }
1586  break;
1587  }
1589  {
1590  uint16_t flags = ntohs (* ((uint16_t *) iterator.this_arg));
1591  if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS))
1592  return 0;
1593  }
1594  break;
1595  } /* end of 'switch' */
1596  } /* end of the 'while' loop */
1597  }
1598  break;
1599  case ARPHRD_IEEE80211:
1600  n = 0; /* no header */
1601  break;
1602  case ARPHRD_ETHER:
1603  {
1604  if (sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
1605  return 0; /* invalid */
1606  GNUNET_memcpy (&buf[sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame)],
1607  tmpbuf + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame),
1608  caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4 /* 4 byte FCS */);
1609  return caplen - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
1610  }
1611  default:
1612  errno = ENOTSUP; /* unsupported format */
1613  return -1;
1614  }
1615  caplen -= n;
1616  if (! got_channel)
1617  ri->ri_channel = linux_get_channel (dev);
1618 
1619  /* detect CRC32 at the end, even if the flag wasn't set and remove it */
1620  if ( (0 == fcs_removed) &&
1621  (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof (uint32_t))) )
1622  {
1623  /* NOTE: this heuristic can of course fail if there happens to
1624  be a matching checksum at the end. Would be good to have
1625  some data to see how often this heuristic actually works. */
1626  caplen -= sizeof (uint32_t);
1627  }
1628  /* copy payload to target buffer */
1629  GNUNET_memcpy (buf, tmpbuf + n, caplen);
1630  return caplen;
1631 }
1632 
1633 
1634 /* ************end of code for reading packets from kernel ************** */
1635 
1636 /* ************other helper functions for main start here ************** */
1637 
1638 
1645 static int
1647 {
1648  struct ifreq ifr;
1649  struct iwreq wrq;
1650  struct packet_mreq mr;
1651  struct sockaddr_ll sll;
1652 
1653  /* find the interface index */
1654  memset (&ifr, 0, sizeof (ifr));
1655  strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1656  if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1657  {
1658  fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1659  IFNAMSIZ, dev->iface, strerror (errno));
1660  return 1;
1661  }
1662 
1663  /* lookup the hardware type */
1664  memset (&sll, 0, sizeof (sll));
1665  sll.sll_family = AF_PACKET;
1666  sll.sll_ifindex = ifr.ifr_ifindex;
1667  sll.sll_protocol = htons (ETH_P_ALL);
1668  if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1669  {
1670  fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1671  IFNAMSIZ, dev->iface, strerror (errno));
1672  return 1;
1673  }
1674  if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1675  (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1676  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1677  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)) )
1678  {
1679  fprintf (stderr, "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
1680  IFNAMSIZ, dev->iface,
1681  ifr.ifr_hwaddr.sa_family);
1682  return 1;
1683  }
1684 
1685  /* lookup iw mode */
1686  memset (&wrq, 0, sizeof (struct iwreq));
1687  strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1688  if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1689  {
1690  /* most probably not supported (ie for rtap ipw interface) *
1691  * so just assume its correctly set... */
1692  wrq.u.mode = IW_MODE_MONITOR;
1693  }
1694 
1695  if ( (wrq.u.mode != IW_MODE_MONITOR) &&
1696  (wrq.u.mode != IW_MODE_ADHOC) )
1697  {
1698  fprintf (stderr, "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
1699  IFNAMSIZ, dev->iface,
1700  wrq.u.mode);
1701  return 1;
1702  }
1703 
1704  /* Is interface st to up, broadcast & running ? */
1705  if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1706  {
1707  /* Bring interface up */
1708  ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1709 
1710  if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1711  {
1712  fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1713  IFNAMSIZ, dev->iface, strerror (errno));
1714  return 1;
1715  }
1716  }
1717 
1718  /* bind the raw socket to the interface */
1719  if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof (sll)))
1720  {
1721  fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1722  dev->iface, strerror (errno));
1723  return 1;
1724  }
1725 
1726  /* lookup the hardware type */
1727  if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1728  {
1729  fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1730  IFNAMSIZ, dev->iface, strerror (errno));
1731  return 1;
1732  }
1733 
1734  GNUNET_memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1735  dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1736  if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1737  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1738  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1739  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1740  {
1741  fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1742  ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1743  return 1;
1744  }
1745 
1746  /* enable promiscuous mode */
1747  memset (&mr, 0, sizeof (mr));
1748  mr.mr_ifindex = sll.sll_ifindex;
1749  mr.mr_type = PACKET_MR_PROMISC;
1750  if (0 !=
1751  setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1752  sizeof (mr)))
1753  {
1754  fprintf (stderr,
1755  "Failed to enable promiscuous mode on interface `%.*s'\n",
1756  IFNAMSIZ,
1757  dev->iface);
1758  return 1;
1759  }
1760  return 0;
1761 }
1762 
1763 
1771 static int
1772 test_wlan_interface (const char *iface)
1773 {
1774  char strbuf[512];
1775  struct stat sbuf;
1776  int ret;
1777 
1778  ret = snprintf (strbuf, sizeof (strbuf),
1779  "/sys/class/net/%s/phy80211/subsystem",
1780  iface);
1781  if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1782  {
1783  fprintf (stderr,
1784  "Did not find 802.11 interface `%s'. Exiting.\n",
1785  iface);
1786  exit (1);
1787  }
1788  return 0;
1789 }
1790 
1791 
1799 static int
1801  const struct HardwareInfos *dev)
1802 {
1803  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1804 
1805  if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1806  (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1807  return 0; /* some drivers set no Macs, then assume it is all for us! */
1808 
1809  if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1810  return 1; /* not a GNUnet ad-hoc package */
1811  if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1812  (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1813  return 0; /* for us, or broadcast */
1814  return 1; /* not for us */
1815 }
1816 
1817 
1824 static void
1826  const struct HardwareInfos *dev)
1827 {
1828  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1829  taIeeeHeader->addr2 = dev->pl_mac;
1830  taIeeeHeader->addr3 = mac_bssid_gnunet;
1831 }
1832 
1833 
1842 static void
1843 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1844 {
1845  struct HardwareInfos *dev = cls;
1847  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
1848  size_t sendsize;
1849  struct RadiotapTransmissionHeader rtheader;
1850  struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
1851 
1852  sendsize = ntohs (hdr->size);
1853  if ( (sendsize <
1854  sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1855  (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1856  {
1857  fprintf (stderr, "Received malformed message\n");
1858  exit (1);
1859  }
1860  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1861  if (MAXLINE < sendsize)
1862  {
1863  fprintf (stderr, "Packet too big for buffer\n");
1864  exit (1);
1865  }
1866  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1867  switch (dev->arptype_in)
1868  {
1870  case ARPHRD_IEEE80211_FULL:
1871  case ARPHRD_IEEE80211:
1872  rtheader.header.it_version = 0;
1873  rtheader.header.it_pad = 0;
1874  rtheader.header.it_len = GNUNET_htole16 (sizeof (rtheader));
1876  rtheader.rate = header->rate;
1877  rtheader.pad1 = 0;
1879  GNUNET_memcpy (write_pout.buf, &rtheader, sizeof (rtheader));
1880  GNUNET_memcpy (&write_pout.buf[sizeof (rtheader)], &header->frame, sendsize);
1881  wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof (rtheader)];
1882 
1883  /* payload contains MAC address, but we don't trust it, so we'll
1884  * overwrite it with OUR MAC address to prevent mischief */
1885  mac_set (wlanheader, dev);
1886  write_pout.size = sendsize + sizeof (rtheader);
1887  break;
1888  case ARPHRD_ETHER:
1889  etheader.dst = header->frame.addr1;
1890  /* etheader.src = header->frame.addr2; --- untrusted input */
1891  etheader.src = dev->pl_mac;
1892  etheader.type = htons (ETH_P_IP);
1893  GNUNET_memcpy (write_pout.buf, &etheader, sizeof (etheader));
1894  GNUNET_memcpy (&write_pout.buf[sizeof (etheader)], &header[1], sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1895  write_pout.size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame) + sizeof (etheader);
1896  break;
1897  default:
1898  fprintf (stderr,
1899  "Unsupported ARPTYPE!\n");
1900  break;
1901  }
1902 }
1903 
1904 
1915 int
1916 main (int argc, char *argv[])
1917 {
1918  struct HardwareInfos dev;
1919  char readbuf[MAXLINE];
1920  int maxfd;
1921  fd_set rfds;
1922  fd_set wfds;
1923  int stdin_open;
1925  int raw_eno;
1926 
1927  /* assert privs so we can modify the firewall rules! */
1928  {
1929 #ifdef HAVE_SETRESUID
1930  uid_t uid = getuid ();
1931 
1932  if (0 != setresuid (uid, 0, 0))
1933  {
1934  fprintf (stderr,
1935  "Failed to setresuid to root: %s\n",
1936  strerror (errno));
1937  return 254;
1938  }
1939 #else
1940  if (0 != seteuid (0))
1941  {
1942  fprintf (stderr,
1943  "Failed to seteuid back to root: %s\n", strerror (errno));
1944  return 254;
1945  }
1946 #endif
1947  }
1948 
1949  /* make use of SGID capabilities on POSIX */
1950  memset (&dev, 0, sizeof (dev));
1951  dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1952  raw_eno = errno; /* remember for later */
1953 
1954  /* now that we've dropped root rights, we can do error checking */
1955  if (2 != argc)
1956  {
1957  fprintf (stderr,
1958  "You must specify the name of the interface as the first and only argument to this program.\n");
1959  if (-1 != dev.fd_raw)
1960  (void) close (dev.fd_raw);
1961  return 1;
1962  }
1963 
1964  if (-1 == dev.fd_raw)
1965  {
1966  fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1967  return 1;
1968  }
1969  if (dev.fd_raw >= FD_SETSIZE)
1970  {
1971  fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1972  dev.fd_raw, FD_SETSIZE);
1973  (void) close (dev.fd_raw);
1974  return 1;
1975  }
1976  if (0 != test_wlan_interface (argv[1]))
1977  {
1978  (void) close (dev.fd_raw);
1979  return 1;
1980  }
1981  strncpy (dev.iface, argv[1], IFNAMSIZ);
1982  if (0 != open_device_raw (&dev))
1983  {
1984  (void) close (dev.fd_raw);
1985  return 1;
1986  }
1987 
1988  /* drop privs */
1989  {
1990  uid_t uid = getuid ();
1991 #ifdef HAVE_SETRESUID
1992  if (0 != setresuid (uid, uid, uid))
1993  {
1994  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1995  if (-1 != dev.fd_raw)
1996  (void) close (dev.fd_raw);
1997  return 1;
1998  }
1999 #else
2000  if (0 != (setuid (uid) | seteuid (uid)))
2001  {
2002  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
2003  if (-1 != dev.fd_raw)
2004  (void) close (dev.fd_raw);
2005  return 1;
2006  }
2007 #endif
2008  }
2009 
2010 
2011  /* send MAC address of the WLAN interface to STDOUT first */
2012  {
2014 
2015  macmsg.hdr.size = htons (sizeof (macmsg));
2017  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
2018  GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2019  write_std.size = sizeof (macmsg);
2020  }
2021 
2022  stdin_mst = mst_create (&stdin_send_hw, &dev);
2023  stdin_open = 1;
2024  while (1)
2025  {
2026  maxfd = -1;
2027  FD_ZERO (&rfds);
2028  if ((0 == write_pout.size) && (1 == stdin_open))
2029  {
2030  FD_SET (STDIN_FILENO, &rfds);
2031  maxfd = MAX (maxfd, STDIN_FILENO);
2032  }
2033  if (0 == write_std.size)
2034  {
2035  FD_SET (dev.fd_raw, &rfds);
2036  maxfd = MAX (maxfd, dev.fd_raw);
2037  }
2038  FD_ZERO (&wfds);
2039  if (0 < write_std.size)
2040  {
2041  FD_SET (STDOUT_FILENO, &wfds);
2042  maxfd = MAX (maxfd, STDOUT_FILENO);
2043  }
2044  if (0 < write_pout.size)
2045  {
2046  FD_SET (dev.fd_raw, &wfds);
2047  maxfd = MAX (maxfd, dev.fd_raw);
2048  }
2049  {
2050  int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
2051  if ((-1 == retval) && (EINTR == errno))
2052  continue;
2053  if (0 > retval)
2054  {
2055  fprintf (stderr, "select failed: %s\n", strerror (errno));
2056  break;
2057  }
2058  }
2059  if (FD_ISSET (STDOUT_FILENO, &wfds))
2060  {
2061  ssize_t ret =
2062  write (STDOUT_FILENO, write_std.buf + write_std.pos,
2064  if (0 > ret)
2065  {
2066  fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
2067  break;
2068  }
2069  write_std.pos += ret;
2070  if (write_std.pos == write_std.size)
2071  {
2072  write_std.pos = 0;
2073  write_std.size = 0;
2074  }
2075  }
2076  if (FD_ISSET (dev.fd_raw, &wfds))
2077  {
2078  ssize_t ret =
2079  write (dev.fd_raw, write_pout.buf + write_pout.pos,
2081  if (0 > ret)
2082  {
2083  fprintf (stderr, "Failed to write to WLAN device: %s\n",
2084  strerror (errno));
2085  break;
2086  }
2087  write_pout.pos += ret;
2088  if ((write_pout.pos != write_pout.size) && (0 != ret))
2089  {
2090  /* we should not get partial sends with packet-oriented devices... */
2091  fprintf (stderr, "Write error, partial send: %u/%u\n",
2092  (unsigned int) write_pout.pos,
2093  (unsigned int) write_pout.size);
2094  break;
2095  }
2096  if (write_pout.pos == write_pout.size)
2097  {
2098  write_pout.pos = 0;
2099  write_pout.size = 0;
2100  }
2101  }
2102 
2103  if (FD_ISSET (STDIN_FILENO, &rfds))
2104  {
2105  ssize_t ret =
2106  read (STDIN_FILENO, readbuf, sizeof (readbuf));
2107  if (0 > ret)
2108  {
2109  fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
2110  break;
2111  }
2112  if (0 == ret)
2113  {
2114  /* stop reading... */
2115  stdin_open = 0;
2116  }
2117  mst_receive (stdin_mst, readbuf, ret);
2118  }
2119 
2120  if (FD_ISSET (dev.fd_raw, &rfds))
2121  {
2123  ssize_t ret;
2124 
2126  ret =
2127  linux_read (&dev, (unsigned char *) &rrm->frame,
2128  sizeof (write_std.buf)
2130  + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2131  rrm);
2132  if (0 > ret)
2133  {
2134  fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2135  break;
2136  }
2137  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2138  {
2139  write_std.size = ret
2141  - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2142  rrm->header.size = htons (write_std.size);
2143  rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2144  }
2145  }
2146  }
2147  /* Error handling, try to clean up a bit at least */
2148  mst_destroy (stdin_mst);
2149  (void) close (dev.fd_raw);
2150  return 1; /* we never exit 'normally' */
2151 }
2152 
2153 /* end of gnunet-helper-transport-wlan.c */
static int iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator over hash map entries.
static int get_channel_from_frequency(int32_t frequency)
Return the channel from the frequency (in Mhz)
uint16_t status
See PRISM_STATUS_*-constants.
#define GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL
Control message between the gnunet-wlan-helper and the daemon (with the MAC).
IO buffer used for buffering data in transit (to wireless or to stdout).
const struct Ieee80211RadiotapHeader * rtheader
pointer to the radiotap header we are walking through
uint32_t did
This has a different ID for each parameter, see PRISM_DID_* constants.
uint64_t ri_mactime
IEEE80211_RADIOTAP_TSFT, 0 if unknown.
#define MAC_ADDR_SIZE
Number fo bytes in a mac address.
#define GNUNET_le32toh(x)
int32_t ri_noise
either IEEE80211_RADIOTAP_DBM_ANTNOISE or IEEE80211_RADIOTAP_DB_ANTNOISE, 0 if unknown.
size_t off
How many bytes in buffer have we already processed?
static struct MessageStreamTokenizer * mst_create(MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
Extension bit, used to indicate that more bits are needed for the bitmask.
#define ARPHRD_IEEE80211_PRISM
Packet format type for the messages we receive from the kernel.
Prism header format (&#39;struct p80211msg&#39; in Linux).
struct GNUNET_MessageHeader hdr
Message header.
#define PRISM_DID_CHANNEL
Channel element.
struct for storing the information of the hardware.
uint32_t data
The data value.
static size_t do_align(size_t start_position, size_t end_position)
Given the start and end position of a block of data, return the end position of that data after align...
Definition: fs_directory.c:484
uint32_t ri_rate
IEEE80211_RADIOTAP_RATE * 50000, 0 if unknown.
#define MIN_BUFFER_SIZE
Smallest supported message.
size_t max_length
length of radiotap header in host byte ordering
IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap.
struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac
MAC address of our own bluetooth interface.
static struct GNUNET_ATS_PerformanceHandle * ph
ATS performance handle used.
Definition: gnunet-ats.c:116
uint16_t txflags
Transmission flags from on the IEEE80211_RADIOTAP_F_TX_* constant family.
#define PRISM_DID_NOISE
Noise element.
static void stdin_send_hw(void *cls, const struct GNUNET_MessageHeader *hdr)
Process data from the stdin.
#define ARPHRD_IEEE80211_FULL
Packet format type for the messages we receive from the kernel.
static int ieee80211_radiotap_iterator_init(struct Ieee80211RadiotapHeaderIterator *iterator, const struct Ieee80211RadiotapHeader *radiotap_header, size_t max_length)
Radiotap header iteration.
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
#define PRISM_MSGCODE_MONITOR
Monitor Frame (indicator that we have a &#39;struct PrismHeader&#39;).
#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK
Bitmask indicating an extension of the bitmask is used.
char devname[16]
Name of the device that captured the packet.
#define GNUNET_NO
Definition: gnunet_common.h:81
static void mac_set(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
Set the wlan header to sane values to make attacks more difficult.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint32_t ri_antenna
IEEE80211_RADIOTAP_ANTENNA, 0 if unknown.
IEEE80211_RADIOTAP_RTS_RETRIES uint8_t data.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define IEEE80211_FC0_TYPE_DATA
IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
size_t pos
How many bytes in buffer are valid right now?
#define PRISM_DEVICE_NAME_LENGTH
Device name length in PRISM frames.
static int ret
Final status code.
Definition: gnunet-arm.c:89
generic definitions for IEEE 802.3 frames
static int linux_get_channel(const struct HardwareInfos *dev)
Get the channel used by our WLAN interface.
static struct SendBuffer write_std
Buffer for data read from the wireless card to be transmitted to stdout.
uint32_t bitmap_shifter
internal shifter for current uint32_t bitmap, (it_present in host byte order), If bit 0 is set...
uint32_t it_present
A bitmap telling which fields are present.
unsigned int this_arg_index
IEEE80211_RADIOTAP_...
Format of a WLAN Control Message.
RadiotapType
Bits in the &#39;it_present&#39; bitmask from the &#39;struct Ieee80211RadiotapHeader&#39;.
Message from the WLAN helper to the plugin: we have received the given message with the given perform...
struct GNUNET_TRANSPORT_WLAN_MacAddress mac
MAC Address of the local WLAN interface.
#define FD_SETSIZE
Definition: winproc.h:39
#define PRISM_STATUS_OK
Value is set (supplied)
IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap.
struct GNUNET_TRANSPORT_WLAN_MacAddress src
Address 2: source address if in ad-hoc-mode or station, BSSID if AP.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint8_t rate
Transmission rate (we use 0, kernel makes up its mind anyway).
#define GNUNET_memcpy(dst, src, n)
size_t size
How many bytes of data are stored in &#39;buf&#39; for transmission right now? Data always starts at offset 0...
IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless.
#define ALIGN_FACTOR
To what multiple do we align messages? 8 byte should suffice for everyone for now.
uint32_t msgcode
We expect this to be a PRISM_MSGCODE_*.
static int check_crc_buf_osdep(const unsigned char *buf, size_t len)
Calculate and check crc of the wlan packet.
Values in the &#39;struct PrismHeader&#39;.
IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from one milliwatt (dBm)
static int mac_test(const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
Test incoming packets mac for being our own.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
#define IEEE80211_RADIOTAP_F_RX_BADFCS
For IEEE80211_RADIOTAP_RX_FLAGS: frame failed crc check.
uint32_t msglen
The length of the entire header.
IEEE80211_RADIOTAP_TSFT __le64 microseconds.
static char buf[2048]
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless.
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_TRANSPORT_WLAN_MacAddress mac_bssid_gnunet
GNUnet bssid.
static int open_device_raw(struct HardwareInfos *dev)
Open the wireless network interface for reading/writing.
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame to transmit (the sender MAC address will be overwritten by the helper as it does not trust...
IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from one milliwatt (dBm)
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER
Type of data messages from the plugin to the gnunet-wlan-helper.
const uint8_t * this_arg
pointer to current radiotap arg
Format of the header we need to prepend to messages to be sent to the Kernel.
#define ARPHRD_ETHER
Packet format type for the messages we receive from the kernel.
#define IEEE80211_RADIOTAP_F_TX_NOSEQ
For IEEE80211_RADIOTAP_TX_FLAGS (&#39;txflags&#39; in &#39;struct RadiotapTransmissionHeader&#39;): sequence number h...
#define GNUNET_htole16(x)
Generic header for radiotap messages (receiving and sending).
#define PRISM_DID_SIGNAL
Signal element.
struct Ieee80211RadiotapHeaderIterator - tracks walk through present radiotap arguments in the radiot...
IEEE80211_RADIOTAP_FLAGS uint8_t bitmap.
uint16_t frame_control
802.11 Frame Control field.
int fd_raw
file descriptor for the raw socket
static unsigned int size
Size of the "table".
Definition: peer.c:67
MessageTokenizerCallback cb
Function to call on completed messages.
static ssize_t linux_read(struct HardwareInfos *dev, unsigned char *buf, size_t buf_size, struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
Read from the raw socket (the wlan card), parse the packet and put the result into the buffer for tra...
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER&#39;.
#define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK
The above &#39;struct RadiotapTransmissionHeader&#39; should have the following value for &#39;header...
const uint32_t * next_bitmap
internal pointer to next present uint32_t (if IEEE80211_RADIOTAP_EXT is used).
#define GNUNET_le16toh(x)
static void mst_destroy(struct MessageStreamTokenizer *mst)
Destroys a tokenizer.
IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap.
static int ieee80211_radiotap_iterator_next(struct Ieee80211RadiotapHeaderIterator *iterator)
Returns the next radiotap parser iterator arg.
#define IEEE80211_RADIOTAP_F_TX_NOACK
For IEEE80211_RADIOTAP_TX_FLAGS (&#39;txflags&#39; in &#39;struct RadiotapTransmissionHeader&#39;): frame should not ...
char buf[4096 *2]
Buffered data; twice the maximum allowed message size as we add some headers.
static int test_wlan_interface(const char *iface)
Test if the given interface name really corresponds to a wireless device.
Handle to a message stream tokenizer.
const uint8_t * arg
internal next argument pointer
#define IEEE80211_RADIOTAP_F_FCS
Bit in IEEE80211_RADIOTAP_FLAGS (which we might get as part of a &#39;struct Ieee80211RadiotapHeader&#39; ext...
enum RadiotapType __attribute__
IEEE80211_RADIOTAP_DATA_RETRIES uint8_t data.
uint32_t ri_channel
IEEE80211_RADIOTAP_CHANNEL, 0 if unknown.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from one milliwatt (dBm)
generic definitions for IEEE 802.11 frames
size_t curr_buf
Size of the buffer (starting at &#39;hdr&#39;).
#define MAXLINE
Maximum size of a message allowed in either direction (used for our receive and sent buffers)...
#define PRISM_DID_MACTIME
Mac time element.
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
int arptype_in
Which format has the header that we&#39;re getting when receiving packets? Some ARPHRD_IEEE80211_XXX-valu...
header for transport plugin and the helper for wlan
int32_t ri_power
from radiotap either IEEE80211_RADIOTAP_DBM_ANTSIGNAL or IEEE80211_RADIOTAP_DB_ANTSIGNAL, 0 if unknown.
static struct SendBuffer write_pout
Buffer for data read from stdin to be transmitted to the wirless card.
char iface[IFNAMSIZ]
Name of the interface, not necessarily 0-terminated (!).
Header for all communications.
#define ARPHRD_IEEE80211
Packet format type for the messages we receive from the kernel.
struct GNUNET_TRANSPORT_WLAN_MacAddress dst
Address 1: destination address in ad-hoc mode or AP, BSSID if station,.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_TRANSPORT_WLAN_MacAddress addr3
Address 3: BSSID in ad-hoc mode, Destination if station, source if AP.
IEEE80211_RADIOTAP_ANTENNA uint8_t antenna index.
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER
Type of data messages from the gnunet-wlan-helper to the plugin.
int main(int argc, char *argv[])
Main function of the helper.
uint16_t it_len
length of the whole header in bytes, including it_version, it_pad, it_len, and data fields...
static const struct GNUNET_TRANSPORT_WLAN_MacAddress bc_all_mac
Broadcast MAC.
static unsigned long calc_crc_osdep(const unsigned char *buf, size_t len)
Calculate crc32, the start of the calculation.
IEEE80211_RADIOTAP_DB_ANTNOISE uint8_t decibel (dB)
unsigned int arg_index
internal next argument index
static int mst_receive(struct MessageStreamTokenizer *mst, const char *buf, size_t size)
Add incoming data to the receive buffer and call the callback for all complete messages.
void(* MessageTokenizerCallback)(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer...
Message from the plugin to the WLAN helper: send the given message with the given connection paramete...
IEEE80211_RADIOTAP_DB_ANTSIGNAL uint8_t decibel (dB)
#define GNUNET_le64toh(x)
#define PRISM_DID_RATE
Rate element, in units/multiples of 500Khz.
size_t pos
How many bytes that were stored in &#39;buf&#39; did we already write to the destination? Always smaller than...
struct GNUNET_TRANSPORT_WLAN_MacAddress addr2
Address 2: source address if in ad-hoc-mode or station, BSSID if AP.
struct GNUNET_TRANSPORT_WLAN_MacAddress addr1
Address 1: destination address in ad-hoc mode or AP, BSSID if station,.
IEEE80211_RADIOTAP_FHSS __le16 see below.
struct Ieee80211RadiotapHeader header
First we begin with the &#39;generic&#39; header we also get when receiving messages.
uint8_t pad1
Padding (we use 0).
IEEE80211_RADIOTAP_RATE uint8_t 500kb/s.