GNUnet  0.11.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 #include <sys/socket.h>
114 #include <sys/ioctl.h>
115 #include <sys/types.h>
116 #include <unistd.h>
117 #include <sys/wait.h>
118 #include <sys/time.h>
119 #include <sys/stat.h>
120 #include <netpacket/packet.h>
121 #include <linux/if_ether.h>
122 #include <linux/if.h>
123 #include <linux/wireless.h>
124 #include <netinet/in.h>
125 #include <linux/if_tun.h>
126 #include <stdio.h>
127 #include <stdlib.h>
128 #include <string.h>
129 #include <stdarg.h>
130 #include <fcntl.h>
131 #include <errno.h>
132 #include <dirent.h>
133 #include <sys/param.h>
134 #include <unistd.h>
135 #include <stdint.h>
136 
137 #include "gnunet_protocols.h"
138 #include "plugin_transport_wlan.h"
139 
145 #define ARPHRD_ETHER 1
146 
147 
153 #define ARPHRD_IEEE80211 801
154 
155 
160 #define ARPHRD_IEEE80211_PRISM 802
161 
167 #define ARPHRD_IEEE80211_FULL 803
168 
169 
174 #define MAXLINE 4096
175 
176 
177 /* ********* structure of messages of type ARPHRD_IEEE80211_PRISM *********** */
178 
183 #define PRISM_DEVICE_NAME_LENGTH 16
184 
188 #define PRISM_MSGCODE_MONITOR 0x0041
189 
195 #define PRISM_DID_MACTIME 0x2041
196 
200 #define PRISM_DID_CHANNEL 0x3041
201 
207 #define PRISM_DID_SIGNAL 0x6041
208 
212 #define PRISM_DID_NOISE 0x7041
213 
217 #define PRISM_DID_RATE 0x8041
218 
219 
223 #define PRISM_STATUS_OK 0
224 
228 #define PRISM_STATUS_NO_VALUE 1
229 
230 
235 {
240  uint32_t did;
241 
245  uint16_t status;
246 
252  uint16_t len;
253 
257  uint32_t data;
258 } __attribute__ ((packed));
259 
260 
265 {
269  uint32_t msgcode;
270 
274  uint32_t msglen;
275 
280 
281  /* followed by 'struct PrismValue's. Documentation suggests that these
282  are typically the hosttime, mactime, channel, rssi, sq, signal, noise,
283  rate, istx and frmlen values, but documentation is sparse. So we
284  will use the 'did' fields to find out what we actually got. */
285 } __attribute__ ((packed));
286 
287 
288 /* ****** end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */
289 
290 /* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */
291 
304 {
313 
321 
328 
342 
351 
360 
370 
379 
388 
398 
406 
414 
422 
429 
436 
443 
450 
456 };
457 
462 #define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK (1 << IEEE80211_RADIOTAP_EXT)
463 
464 
473 #define IEEE80211_RADIOTAP_F_CFP 0x01
474 
483 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
484 
493 #define IEEE80211_RADIOTAP_F_WEP 0x04
494 
503 #define IEEE80211_RADIOTAP_F_FRAG 0x08
504 
513 #define IEEE80211_RADIOTAP_F_FCS 0x10
514 
524 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20
525 
526 
531 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
532 
537 #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
538 
543 #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
544 
549 #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
550 
555 #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008
556 
561 #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010
562 
563 
579 {
584  uint8_t it_version;
585 
589  uint8_t it_pad;
590 
595  uint16_t it_len;
596 
602  uint32_t it_present;
603 };
604 
605 
611 {
616  struct Ieee80211RadiotapHeader header;
617 
621  uint8_t rate;
622 
629  uint8_t pad1;
630 
634  uint16_t txflags;
635 };
636 
642 #define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 \
643  << \
644  IEEE80211_RADIOTAP_RATE) \
645  | (1 \
646  << \
647  IEEE80211_RADIOTAP_TX_FLAGS))
648 
649 
655 {
660 
664  const uint8_t *this_arg;
665 
669  const uint8_t *arg;
670 
674  const uint32_t *next_bitmap;
675 
679  size_t max_length;
680 
685  uint32_t bitmap_shifter;
686 
690  unsigned int this_arg_index;
691 
695  unsigned int arg_index;
696 };
697 
698 
699 /* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
700 
701 /* ************************** our globals ******************************* */
702 
707 struct HardwareInfos
708 {
712  int fd_raw;
713 
719 
723  char iface[IFNAMSIZ];
724 
728  struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
729 };
730 
731 
735 struct SendBuffer
736 {
741  size_t size;
742 
747  size_t pos;
748 
753  char buf[MAXLINE * 2];
754 };
755 
756 
760 static struct SendBuffer write_pout;
761 
765 static struct SendBuffer write_std;
766 
767 
768 /* *********** specialized version of server_mst.c begins here ********** */
769 
774 #define ALIGN_FACTOR 8
775 
779 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
780 
781 
789 typedef void (*MessageTokenizerCallback) (void *cls,
790  const struct
792  message);
793 
798 {
803 
807  void *cb_cls;
808 
812  size_t curr_buf;
813 
817  size_t off;
818 
822  size_t pos;
823 
827  struct GNUNET_MessageHeader *hdr;
828 };
829 
830 
838 static struct MessageStreamTokenizer *
840  void *cb_cls)
841 {
842  struct MessageStreamTokenizer *ret;
843 
844  ret = malloc (sizeof(struct MessageStreamTokenizer));
845  if (NULL == ret)
846  {
847  fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
848  exit (1);
849  }
850  ret->hdr = malloc (MIN_BUFFER_SIZE);
851  if (NULL == ret->hdr)
852  {
853  fprintf (stderr, "Failed to allocate buffer for alignment\n");
854  exit (1);
855  }
856  ret->curr_buf = MIN_BUFFER_SIZE;
857  ret->cb = cb;
858  ret->cb_cls = cb_cls;
859  return ret;
860 }
861 
862 
873 static int
875  const char *buf, size_t size)
876 {
877  const struct GNUNET_MessageHeader *hdr;
878  size_t delta;
879  uint16_t want;
880  char *ibuf;
881  int need_align;
882  unsigned long offset;
883  int ret;
884 
885  ret = GNUNET_OK;
886  ibuf = (char *) mst->hdr;
887  while (mst->pos > 0)
888  {
889 do_align:
890  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
891  (0 != (mst->off % ALIGN_FACTOR)))
892  {
893  /* need to align or need more space */
894  mst->pos -= mst->off;
895  memmove (ibuf, &ibuf[mst->off], mst->pos);
896  mst->off = 0;
897  }
898  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
899  {
900  delta =
901  GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
902  - (mst->pos - mst->off), size);
903  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
904  mst->pos += delta;
905  buf += delta;
906  size -= delta;
907  }
908  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
909  {
910  return GNUNET_OK;
911  }
912  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
913  want = ntohs (hdr->size);
914  if (want < sizeof(struct GNUNET_MessageHeader))
915  {
916  fprintf (stderr,
917  "Received invalid message from stdin\n");
918  exit (1);
919  }
920  if (mst->curr_buf - mst->off < want)
921  {
922  /* need more space */
923  mst->pos -= mst->off;
924  memmove (ibuf, &ibuf[mst->off], mst->pos);
925  mst->off = 0;
926  }
927  if (want > mst->curr_buf)
928  {
929  mst->hdr = realloc (mst->hdr, want);
930  if (NULL == mst->hdr)
931  {
932  fprintf (stderr, "Failed to allocate buffer for alignment\n");
933  exit (1);
934  }
935  ibuf = (char *) mst->hdr;
936  mst->curr_buf = want;
937  }
938  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
939  if (mst->pos - mst->off < want)
940  {
941  delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
942  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
943  mst->pos += delta;
944  buf += delta;
945  size -= delta;
946  }
947  if (mst->pos - mst->off < want)
948  {
949  return GNUNET_OK;
950  }
951  mst->cb (mst->cb_cls, hdr);
952  mst->off += want;
953  if (mst->off == mst->pos)
954  {
955  /* reset to beginning of buffer, it's free right now! */
956  mst->off = 0;
957  mst->pos = 0;
958  }
959  }
960  while (size > 0)
961  {
962  if (size < sizeof(struct GNUNET_MessageHeader))
963  break;
964  offset = (unsigned long) buf;
965  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
966  if (GNUNET_NO == need_align)
967  {
968  /* can try to do zero-copy and process directly from original buffer */
969  hdr = (const struct GNUNET_MessageHeader *) buf;
970  want = ntohs (hdr->size);
971  if (want < sizeof(struct GNUNET_MessageHeader))
972  {
973  fprintf (stderr,
974  "Received invalid message from stdin\n");
975  exit (1);
976  }
977  if (size < want)
978  break; /* or not, buffer incomplete, so copy to private buffer... */
979  mst->cb (mst->cb_cls, hdr);
980  buf += want;
981  size -= want;
982  }
983  else
984  {
985  /* need to copy to private buffer to align;
986  * yes, we go a bit more spagetti than usual here */
987  goto do_align;
988  }
989  }
990  if (size > 0)
991  {
992  if (size + mst->pos > mst->curr_buf)
993  {
994  mst->hdr = realloc (mst->hdr, size + mst->pos);
995  if (NULL == mst->hdr)
996  {
997  fprintf (stderr, "Failed to allocate buffer for alignment\n");
998  exit (1);
999  }
1000  ibuf = (char *) mst->hdr;
1001  mst->curr_buf = size + mst->pos;
1002  }
1003  if (mst->pos + size > mst->curr_buf)
1004  {
1005  fprintf (stderr,
1006  "Assertion failed\n");
1007  exit (1);
1008  }
1009  GNUNET_memcpy (&ibuf[mst->pos], buf, size);
1010  mst->pos += size;
1011  }
1012  return ret;
1013 }
1014 
1015 
1021 static void
1023 {
1024  free (mst->hdr);
1025  free (mst);
1026 }
1027 
1028 
1029 /* ***************** end of server_mst.c clone ***************** **/
1030 
1031 
1032 /* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */
1033 
1051 static int
1054  const struct
1055  Ieee80211RadiotapHeader *radiotap_header,
1056  size_t max_length)
1057 {
1058  if ((iterator == NULL) ||
1059  (radiotap_header == NULL))
1060  return -1;
1061 
1062  /* Linux only supports version 0 radiotap format */
1063  if (0 != radiotap_header->it_version)
1064  return -1;
1065 
1066  /* sanity check for allowed length and radiotap length field */
1067  if ((max_length < sizeof(struct Ieee80211RadiotapHeader)) ||
1068  (max_length < (GNUNET_le16toh (radiotap_header->it_len))))
1069  return -1;
1070 
1071  memset (iterator, 0, sizeof(struct Ieee80211RadiotapHeaderIterator));
1072  iterator->rtheader = radiotap_header;
1073  iterator->max_length = GNUNET_le16toh (radiotap_header->it_len);
1074  iterator->bitmap_shifter = GNUNET_le32toh (radiotap_header->it_present);
1075  iterator->arg = ((uint8_t *) radiotap_header) + sizeof(struct
1077 
1078  /* find payload start allowing for extended bitmap(s) */
1080  {
1081  while (GNUNET_le32toh (*((uint32_t *) iterator->arg))
1083  {
1084  iterator->arg += sizeof(uint32_t);
1085  /*
1086  * check for insanity where the present bitmaps
1087  * keep claiming to extend up to or even beyond the
1088  * stated radiotap header length
1089  */if (iterator->arg - ((uint8_t*) iterator->rtheader) >
1090  iterator->max_length)
1091  return -1;
1092  }
1093  iterator->arg += sizeof(uint32_t);
1094  /*
1095  * no need to check again for blowing past stated radiotap
1096  * header length, becuase ieee80211_radiotap_iterator_next
1097  * checks it before it is dereferenced
1098  */}
1099  /* we are all initialized happily */
1100  return 0;
1101 }
1102 
1103 
1116 static int
1119 {
1120  /*
1121  * small length lookup table for all radiotap types we heard of
1122  * starting from b0 in the bitmap, so we can walk the payload
1123  * area of the radiotap header
1124  *
1125  * There is a requirement to pad args, so that args
1126  * of a given length must begin at a boundary of that length
1127  * -- but note that compound args are allowed (eg, 2 x uint16_t
1128  * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
1129  * a reliable indicator of alignment requirement.
1130  *
1131  * upper nybble: content alignment for arg
1132  * lower nybble: content length for arg
1133  */static const uint8_t rt_sizes[] = {
1134  [IEEE80211_RADIOTAP_TSFT] = 0x88,
1135  [IEEE80211_RADIOTAP_FLAGS] = 0x11,
1136  [IEEE80211_RADIOTAP_RATE] = 0x11,
1137  [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
1138  [IEEE80211_RADIOTAP_FHSS] = 0x22,
1145  [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
1148  [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
1149  [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
1152  /*
1153  * add more here as they are defined in
1154  * include/net/ieee80211_radiotap.h
1155  */
1156  };
1157 
1158  /*
1159  * for every radiotap entry we can at
1160  * least skip (by knowing the length)...
1161  */
1162  while (iterator->arg_index < sizeof(rt_sizes))
1163  {
1164  int hit = (0 != (iterator->bitmap_shifter & 1));
1165 
1166  if (hit)
1167  {
1168  unsigned int wanted_alignment;
1169  unsigned int unalignment;
1170  /*
1171  * arg is present, account for alignment padding
1172  * 8-bit args can be at any alignment
1173  * 16-bit args must start on 16-bit boundary
1174  * 32-bit args must start on 32-bit boundary
1175  * 64-bit args must start on 64-bit boundary
1176  *
1177  * note that total arg size can differ from alignment of
1178  * elements inside arg, so we use upper nybble of length table
1179  * to base alignment on. First, 'wanted_alignment' is set to be
1180  * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit
1181  * arguments. Then, we calculate the 'unalignment' (how many
1182  * bytes we are over by taking the difference of 'arg' and the
1183  * overall starting point modulo the desired alignment. As
1184  * desired alignments are powers of two, we can do modulo with
1185  * binary "&" (and also avoid the possibility of a division by
1186  * zero if the 'rt_sizes' table contains bogus entries).
1187  *
1188  * also note: these alignments are relative to the start of the
1189  * radiotap header. There is no guarantee that the radiotap
1190  * header itself is aligned on any kind of boundary, thus we
1191  * need to really look at the delta here.
1192  */wanted_alignment = rt_sizes[iterator->arg_index] >> 4;
1193  unalignment = (((void *) iterator->arg) - ((void *) iterator->rtheader))
1194  & (wanted_alignment - 1);
1195  if (0 != unalignment)
1196  {
1197  /* need padding (by 'wanted_alignment - unalignment') */
1198  iterator->arg_index += wanted_alignment - unalignment;
1199  }
1200 
1201  /*
1202  * this is what we will return to user, but we need to
1203  * move on first so next call has something fresh to test
1204  */
1205  iterator->this_arg_index = iterator->arg_index;
1206  iterator->this_arg = iterator->arg;
1207 
1208  /* internally move on the size of this arg (using lower nybble from
1209  the table) */
1210  iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
1211 
1212  /*
1213  * check for insanity where we are given a bitmap that
1214  * claims to have more arg content than the length of the
1215  * radiotap section. We will normally end up equalling this
1216  * max_length on the last arg, never exceeding it.
1217  */if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
1218  iterator->max_length)
1219  return -1;
1220  }
1221 
1222  /* Now, move on to next bit / next entry */
1223  iterator->arg_index++;
1224 
1225  if (0 == (iterator->arg_index % 32))
1226  {
1227  /* completed current uint32_t bitmap */
1228  if (0 != (iterator->bitmap_shifter & 1))
1229  {
1230  /* bit 31 was set, there is more; move to next uint32_t bitmap */
1231  iterator->bitmap_shifter = GNUNET_le32toh (*iterator->next_bitmap);
1232  iterator->next_bitmap++;
1233  }
1234  else
1235  {
1236  /* no more bitmaps: end (by setting arg_index to high, unsupported value) */
1237  iterator->arg_index = sizeof(rt_sizes);
1238  }
1239  }
1240  else
1241  {
1242  /* just try the next bit (while loop will move on) */
1243  iterator->bitmap_shifter >>= 1;
1244  }
1245 
1246  /* if we found a valid arg earlier, return it now */
1247  if (hit)
1248  return iterator->this_arg_index;
1249  }
1250 
1251  /* we don't know how to handle any more args (or there are no more),
1252  so we're done (this is not an error) */
1253  return -1;
1254 }
1255 
1256 
1264 static unsigned long
1265 calc_crc_osdep (const unsigned char *buf, size_t len)
1266 {
1267  static const unsigned long int crc_tbl_osdep[256] = {
1268  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1269  0xE963A535, 0x9E6495A3,
1270  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
1271  0xE7B82D07, 0x90BF1D91,
1272  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
1273  0xF4D4B551, 0x83D385C7,
1274  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1275  0xFA0F3D63, 0x8D080DF5,
1276  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
1277  0xD20D85FD, 0xA50AB56B,
1278  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
1279  0xDCD60DCF, 0xABD13D59,
1280  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1281  0xCFBA9599, 0xB8BDA50F,
1282  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
1283  0xC1611DAB, 0xB6662D3D,
1284  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
1285  0x9FBFE4A5, 0xE8B8D433,
1286  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1287  0x91646C97, 0xE6635C01,
1288  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
1289  0x8208F4C1, 0xF50FC457,
1290  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
1291  0x8CD37CF3, 0xFBD44C65,
1292  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1293  0xA4D1C46D, 0xD3D6F4FB,
1294  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
1295  0xAA0A4C5F, 0xDD0D7CC9,
1296  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
1297  0xB966D409, 0xCE61E49F,
1298  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1299  0xB7BD5C3B, 0xC0BA6CAD,
1300  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1301  0x04DB2615, 0x73DC1683,
1302  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1303  0x0A00AE27, 0x7D079EB1,
1304  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1305  0x196C3671, 0x6E6B06E7,
1306  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1307  0x17B7BE43, 0x60B08ED5,
1308  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1309  0x3FB506DD, 0x48B2364B,
1310  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1311  0x316E8EEF, 0x4669BE79,
1312  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1313  0x220216B9, 0x5505262F,
1314  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1315  0x2CD99E8B, 0x5BDEAE1D,
1316  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1317  0x72076785, 0x05005713,
1318  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1319  0x7CDCEFB7, 0x0BDBDF21,
1320  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1321  0x6FB077E1, 0x18B74777,
1322  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1323  0x616BFFD3, 0x166CCF45,
1324  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1325  0x4969474D, 0x3E6E77DB,
1326  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1327  0x47B2CF7F, 0x30B5FFE9,
1328  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1329  0x54DE5729, 0x23D967BF,
1330  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1331  0x5A05DF1B, 0x2D02EF8D
1332  };
1333 
1334  unsigned long crc = 0xFFFFFFFF;
1335 
1336  for (; len > 0; len--, buf++)
1337  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1338  return(~crc);
1339 }
1340 
1341 
1350 static int
1351 check_crc_buf_osdep (const unsigned char *buf, size_t len)
1352 {
1353  unsigned long crc;
1354 
1355  crc = calc_crc_osdep (buf, len);
1356  buf += len;
1357  if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
1358  ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
1359  return 0;
1360  return 1;
1361 }
1362 
1363 
1364 /* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */
1365 
1366 
1367 /* ************beginning of code for reading packets from kernel ************** */
1368 
1375 static int
1376 get_channel_from_frequency (int32_t frequency)
1377 {
1378  if ((frequency >= 2412) && (frequency <= 2472))
1379  return (frequency - 2407) / 5;
1380  if (frequency == 2484)
1381  return 14;
1382  if ((frequency >= 5000) && (frequency <= 6100))
1383  return (frequency - 5000) / 5;
1384  return -1;
1385 }
1386 
1387 
1394 static int
1396 {
1397  struct iwreq wrq;
1398  int32_t frequency;
1399 
1400  memset (&wrq, 0, sizeof(struct iwreq));
1401  strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1402  if (0 > ioctl (dev->fd_raw, SIOCGIWFREQ, &wrq))
1403  return -1;
1404  frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */
1405  if (100000000 < frequency)
1406  frequency /= 100000;
1407  else if (1000000 < frequency)
1408  frequency /= 1000;
1409  if (1000 < frequency)
1410  return get_channel_from_frequency (frequency);
1411  return frequency;
1412 }
1413 
1414 
1426 static ssize_t
1428  unsigned char *buf, size_t buf_size,
1430 {
1431  unsigned char tmpbuf[buf_size];
1432  ssize_t caplen;
1433  size_t n;
1434  int got_signal = 0;
1435  int got_noise = 0;
1436  int got_channel = 0;
1437  int fcs_removed = 0;
1438 
1439  caplen = read (dev->fd_raw, tmpbuf, buf_size);
1440  if (0 > caplen)
1441  {
1442  if (EAGAIN == errno)
1443  return 0;
1444  fprintf (stderr, "Failed to read from RAW socket: %s\n", strerror (errno));
1445  return -1;
1446  }
1447 
1448  memset (ri, 0, sizeof(*ri));
1449  switch (dev->arptype_in)
1450  {
1452  {
1453  const struct PrismHeader *ph;
1454 
1455  ph = (const struct PrismHeader*) tmpbuf;
1456  n = ph->msglen;
1457  if ((n < 8) || (n >= caplen))
1458  return 0; /* invalid format */
1459  if ((PRISM_MSGCODE_MONITOR == ph->msgcode) &&
1460  (n >= sizeof(struct PrismHeader)))
1461  {
1462  const char *pos;
1463  size_t left;
1464  struct PrismValue pv;
1465 
1466  left = n - sizeof(struct PrismHeader);
1467  pos = (const char *) &ph[1];
1468  while (left > sizeof(struct PrismValue))
1469  {
1470  left -= sizeof(struct PrismValue);
1471  GNUNET_memcpy (&pv, pos, sizeof(struct PrismValue));
1472  pos += sizeof(struct PrismValue);
1473 
1474  switch (pv.did)
1475  {
1476  case PRISM_DID_NOISE:
1477  if (PRISM_STATUS_OK == pv.status)
1478  {
1479  ri->ri_noise = pv.data;
1480  /* got_noise = 1; */
1481  }
1482  break;
1483 
1484  case PRISM_DID_RATE:
1485  if (PRISM_STATUS_OK == pv.status)
1486  ri->ri_rate = pv.data * 500000;
1487  break;
1488 
1489  case PRISM_DID_CHANNEL:
1490  if (PRISM_STATUS_OK == pv.status)
1491  {
1492  ri->ri_channel = pv.data;
1493  got_channel = 1;
1494  }
1495  break;
1496 
1497  case PRISM_DID_MACTIME:
1498  if (PRISM_STATUS_OK == pv.status)
1499  ri->ri_mactime = pv.data;
1500  break;
1501 
1502  case PRISM_DID_SIGNAL:
1503  if (PRISM_STATUS_OK == pv.status)
1504  {
1505  ri->ri_power = pv.data;
1506  /* got_signal = 1; */
1507  }
1508  break;
1509  }
1510  }
1511  }
1512  if ((n < 8) || (n >= caplen))
1513  return 0; /* invalid format */
1514  }
1515  break;
1516 
1517  case ARPHRD_IEEE80211_FULL:
1518  {
1519  struct Ieee80211RadiotapHeaderIterator iterator;
1520  struct Ieee80211RadiotapHeader *rthdr;
1521 
1522  memset (&iterator, 0, sizeof(iterator));
1523  rthdr = (struct Ieee80211RadiotapHeader *) tmpbuf;
1524  n = GNUNET_le16toh (rthdr->it_len);
1525  if ((n < sizeof(struct Ieee80211RadiotapHeader)) || (n >= caplen))
1526  return 0; /* invalid 'it_len' */
1527  if (0 != ieee80211_radiotap_iterator_init (&iterator, rthdr, caplen))
1528  return 0;
1529  /* go through the radiotap arguments we have been given by the driver */
1530  while (0 <= ieee80211_radiotap_iterator_next (&iterator))
1531  {
1532  switch (iterator.this_arg_index)
1533  {
1535  ri->ri_mactime = GNUNET_le64toh (*((uint64_t *) iterator.this_arg));
1536  break;
1537 
1539  if (! got_signal)
1540  {
1541  ri->ri_power = *((int8_t*) iterator.this_arg);
1542  got_signal = 1;
1543  }
1544  break;
1545 
1547  if (! got_signal)
1548  {
1549  ri->ri_power = *((int8_t*) iterator.this_arg);
1550  got_signal = 1;
1551  }
1552  break;
1553 
1555  if (! got_noise)
1556  {
1557  ri->ri_noise = *((int8_t*) iterator.this_arg);
1558  got_noise = 1;
1559  }
1560  break;
1561 
1563  if (! got_noise)
1564  {
1565  ri->ri_noise = *((int8_t*) iterator.this_arg);
1566  got_noise = 1;
1567  }
1568  break;
1569 
1571  ri->ri_antenna = *iterator.this_arg;
1572  break;
1573 
1575  ri->ri_channel = *iterator.this_arg;
1576  got_channel = 1;
1577  break;
1578 
1580  ri->ri_rate = (*iterator.this_arg) * 500000;
1581  break;
1582 
1584  {
1585  uint8_t flags = *iterator.this_arg;
1586  /* is the CRC visible at the end? if so, remove */
1587  if (0 != (flags & IEEE80211_RADIOTAP_F_FCS))
1588  {
1589  fcs_removed = 1;
1590  caplen -= sizeof(uint32_t);
1591  }
1592  break;
1593  }
1594 
1596  {
1597  uint16_t flags = ntohs (*((uint16_t *) iterator.this_arg));
1598  if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS))
1599  return 0;
1600  }
1601  break;
1602  } /* end of 'switch' */
1603  } /* end of the 'while' loop */
1604  }
1605  break;
1606 
1607  case ARPHRD_IEEE80211:
1608  n = 0; /* no header */
1609  break;
1610 
1611  case ARPHRD_ETHER:
1612  {
1613  if (sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
1614  return 0; /* invalid */
1616  tmpbuf + sizeof(struct
1618  caplen - sizeof(struct
1620  - 4 /* 4 byte FCS */);
1621  return caplen - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
1622  }
1623 
1624  default:
1625  errno = ENOTSUP; /* unsupported format */
1626  return -1;
1627  }
1628  caplen -= n;
1629  if (! got_channel)
1630  ri->ri_channel = linux_get_channel (dev);
1631 
1632  /* detect CRC32 at the end, even if the flag wasn't set and remove it */
1633  if ((0 == fcs_removed) &&
1634  (0 == check_crc_buf_osdep (tmpbuf + n, caplen - sizeof(uint32_t))))
1635  {
1636  /* NOTE: this heuristic can of course fail if there happens to
1637  be a matching checksum at the end. Would be good to have
1638  some data to see how often this heuristic actually works. */
1639  caplen -= sizeof(uint32_t);
1640  }
1641  /* copy payload to target buffer */
1642  GNUNET_memcpy (buf, tmpbuf + n, caplen);
1643  return caplen;
1644 }
1645 
1646 
1647 /* ************end of code for reading packets from kernel ************** */
1648 
1649 /* ************other helper functions for main start here ************** */
1650 
1651 
1658 static int
1660 {
1661  struct ifreq ifr;
1662  struct iwreq wrq;
1663  struct packet_mreq mr;
1664  struct sockaddr_ll sll;
1665 
1666  /* find the interface index */
1667  memset (&ifr, 0, sizeof(ifr));
1668  strncpy (ifr.ifr_name, dev->iface, IFNAMSIZ);
1669  if (-1 == ioctl (dev->fd_raw, SIOCGIFINDEX, &ifr))
1670  {
1671  fprintf (stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1672  IFNAMSIZ, dev->iface, strerror (errno));
1673  return 1;
1674  }
1675 
1676  /* lookup the hardware type */
1677  memset (&sll, 0, sizeof(sll));
1678  sll.sll_family = AF_PACKET;
1679  sll.sll_ifindex = ifr.ifr_ifindex;
1680  sll.sll_protocol = htons (ETH_P_ALL);
1681  if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1682  {
1683  fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1684  IFNAMSIZ, dev->iface, strerror (errno));
1685  return 1;
1686  }
1687  if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1688  (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1689  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1690  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)))
1691  {
1692  fprintf (stderr,
1693  "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
1694  IFNAMSIZ, dev->iface,
1695  ifr.ifr_hwaddr.sa_family);
1696  return 1;
1697  }
1698 
1699  /* lookup iw mode */
1700  memset (&wrq, 0, sizeof(struct iwreq));
1701  strncpy (wrq.ifr_name, dev->iface, IFNAMSIZ);
1702  if (-1 == ioctl (dev->fd_raw, SIOCGIWMODE, &wrq))
1703  {
1704  /* most probably not supported (ie for rtap ipw interface) *
1705  * so just assume its correctly set... */
1706  wrq.u.mode = IW_MODE_MONITOR;
1707  }
1708 
1709  if ((wrq.u.mode != IW_MODE_MONITOR) &&
1710  (wrq.u.mode != IW_MODE_ADHOC))
1711  {
1712  fprintf (stderr,
1713  "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
1714  IFNAMSIZ, dev->iface,
1715  wrq.u.mode);
1716  return 1;
1717  }
1718 
1719  /* Is interface st to up, broadcast & running ? */
1720  if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1721  {
1722  /* Bring interface up */
1723  ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1724 
1725  if (-1 == ioctl (dev->fd_raw, SIOCSIFFLAGS, &ifr))
1726  {
1727  fprintf (stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1728  IFNAMSIZ, dev->iface, strerror (errno));
1729  return 1;
1730  }
1731  }
1732 
1733  /* bind the raw socket to the interface */
1734  if (-1 == bind (dev->fd_raw, (struct sockaddr *) &sll, sizeof(sll)))
1735  {
1736  fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1737  dev->iface, strerror (errno));
1738  return 1;
1739  }
1740 
1741  /* lookup the hardware type */
1742  if (-1 == ioctl (dev->fd_raw, SIOCGIFHWADDR, &ifr))
1743  {
1744  fprintf (stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1745  IFNAMSIZ, dev->iface, strerror (errno));
1746  return 1;
1747  }
1748 
1749  GNUNET_memcpy (&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1750  dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1751  if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1752  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1753  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1754  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1755  {
1756  fprintf (stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1757  ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1758  return 1;
1759  }
1760 
1761  /* enable promiscuous mode */
1762  memset (&mr, 0, sizeof(mr));
1763  mr.mr_ifindex = sll.sll_ifindex;
1764  mr.mr_type = PACKET_MR_PROMISC;
1765  if (0 !=
1766  setsockopt (dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1767  sizeof(mr)))
1768  {
1769  fprintf (stderr,
1770  "Failed to enable promiscuous mode on interface `%.*s'\n",
1771  IFNAMSIZ,
1772  dev->iface);
1773  return 1;
1774  }
1775  return 0;
1776 }
1777 
1778 
1786 static int
1787 test_wlan_interface (const char *iface)
1788 {
1789  char strbuf[512];
1790  struct stat sbuf;
1791  int ret;
1792 
1793  ret = snprintf (strbuf, sizeof(strbuf),
1794  "/sys/class/net/%s/phy80211/subsystem",
1795  iface);
1796  if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1797  {
1798  fprintf (stderr,
1799  "Did not find 802.11 interface `%s'. Exiting.\n",
1800  iface);
1801  exit (1);
1802  }
1803  return 0;
1804 }
1805 
1806 
1814 static int
1816  const struct HardwareInfos *dev)
1817 {
1818  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1819 
1820  if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1821  (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1822  return 0; /* some drivers set no Macs, then assume it is all for us! */
1823 
1824  if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1825  return 1; /* not a GNUnet ad-hoc package */
1826  if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1827  (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1828  return 0; /* for us, or broadcast */
1829  return 1; /* not for us */
1830 }
1831 
1832 
1839 static void
1841  const struct HardwareInfos *dev)
1842 {
1843  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1844  taIeeeHeader->addr2 = dev->pl_mac;
1845  taIeeeHeader->addr3 = mac_bssid_gnunet;
1846 }
1847 
1848 
1857 static void
1858 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1859 {
1860  struct HardwareInfos *dev = cls;
1862  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
1863  size_t sendsize;
1864  struct RadiotapTransmissionHeader rtheader;
1865  struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
1866 
1867  sendsize = ntohs (hdr->size);
1868  if ((sendsize <
1871  {
1872  fprintf (stderr, "Received malformed message\n");
1873  exit (1);
1874  }
1875  sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1876  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1877  if (MAXLINE < sendsize)
1878  {
1879  fprintf (stderr, "Packet too big for buffer\n");
1880  exit (1);
1881  }
1882  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1883  switch (dev->arptype_in)
1884  {
1886  case ARPHRD_IEEE80211_FULL:
1887  case ARPHRD_IEEE80211:
1888  rtheader.header.it_version = 0;
1889  rtheader.header.it_pad = 0;
1890  rtheader.header.it_len = GNUNET_htole16 (sizeof(rtheader));
1891  rtheader.header.it_present = GNUNET_htole16 (
1893  rtheader.rate = header->rate;
1894  rtheader.pad1 = 0;
1897  GNUNET_memcpy (write_pout.buf, &rtheader, sizeof(rtheader));
1898  GNUNET_memcpy (&write_pout.buf[sizeof(rtheader)], &header->frame, sendsize);
1899  wlanheader = (struct
1900  GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf[sizeof(
1901  rtheader)
1902  ];
1903 
1904  /* payload contains MAC address, but we don't trust it, so we'll
1905  * overwrite it with OUR MAC address to prevent mischief */
1906  mac_set (wlanheader, dev);
1907  write_pout.size = sendsize + sizeof(rtheader);
1908  break;
1909 
1910  case ARPHRD_ETHER:
1911  etheader.dst = header->frame.addr1;
1912  /* etheader.src = header->frame.addr2; --- untrusted input */
1913  etheader.src = dev->pl_mac;
1914  etheader.type = htons (ETH_P_IP);
1915  GNUNET_memcpy (write_pout.buf, &etheader, sizeof(etheader));
1916  GNUNET_memcpy (&write_pout.buf[sizeof(etheader)], &header[1], sendsize
1917  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1918  write_pout.size = sendsize - sizeof(struct
1919  GNUNET_TRANSPORT_WLAN_Ieee80211Frame)
1920  + sizeof(etheader);
1921  break;
1922 
1923  default:
1924  fprintf (stderr,
1925  "Unsupported ARPTYPE!\n");
1926  break;
1927  }
1928 }
1929 
1930 
1941 int
1942 main (int argc, char *argv[])
1943 {
1944  struct HardwareInfos dev;
1945  char readbuf[MAXLINE];
1946  int maxfd;
1947  fd_set rfds;
1948  fd_set wfds;
1949  int stdin_open;
1951  int raw_eno;
1952 
1953  /* assert privs so we can modify the firewall rules! */
1954  {
1955 #ifdef HAVE_SETRESUID
1956  uid_t uid = getuid ();
1957 
1958  if (0 != setresuid (uid, 0, 0))
1959  {
1960  fprintf (stderr,
1961  "Failed to setresuid to root: %s\n",
1962  strerror (errno));
1963  return 254;
1964  }
1965 #else
1966  if (0 != seteuid (0))
1967  {
1968  fprintf (stderr,
1969  "Failed to seteuid back to root: %s\n", strerror (errno));
1970  return 254;
1971  }
1972 #endif
1973  }
1974 
1975  /* make use of SGID capabilities on POSIX */
1976  memset (&dev, 0, sizeof(dev));
1977  dev.fd_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
1978  raw_eno = errno; /* remember for later */
1979 
1980  /* now that we've dropped root rights, we can do error checking */
1981  if (2 != argc)
1982  {
1983  fprintf (stderr,
1984  "You must specify the name of the interface as the first and only argument to this program.\n");
1985  if (-1 != dev.fd_raw)
1986  (void) close (dev.fd_raw);
1987  return 1;
1988  }
1989 
1990  if (-1 == dev.fd_raw)
1991  {
1992  fprintf (stderr, "Failed to create raw socket: %s\n", strerror (raw_eno));
1993  return 1;
1994  }
1995  if (dev.fd_raw >= FD_SETSIZE)
1996  {
1997  fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1998  dev.fd_raw, FD_SETSIZE);
1999  (void) close (dev.fd_raw);
2000  return 1;
2001  }
2002  if (0 != test_wlan_interface (argv[1]))
2003  {
2004  (void) close (dev.fd_raw);
2005  return 1;
2006  }
2007  strncpy (dev.iface, argv[1], IFNAMSIZ);
2008  if (0 != open_device_raw (&dev))
2009  {
2010  (void) close (dev.fd_raw);
2011  return 1;
2012  }
2013 
2014  /* drop privs */
2015  {
2016  uid_t uid = getuid ();
2017 #ifdef HAVE_SETRESUID
2018  if (0 != setresuid (uid, uid, uid))
2019  {
2020  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
2021  if (-1 != dev.fd_raw)
2022  (void) close (dev.fd_raw);
2023  return 1;
2024  }
2025 #else
2026  if (0 != (setuid (uid) | seteuid (uid)))
2027  {
2028  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
2029  if (-1 != dev.fd_raw)
2030  (void) close (dev.fd_raw);
2031  return 1;
2032  }
2033 #endif
2034  }
2035 
2036 
2037  /* send MAC address of the WLAN interface to STDOUT first */
2038  {
2040 
2041  macmsg.hdr.size = htons (sizeof(macmsg));
2043  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
2045  GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
2046  write_std.size = sizeof(macmsg);
2047  }
2048 
2049  stdin_mst = mst_create (&stdin_send_hw, &dev);
2050  stdin_open = 1;
2051  while (1)
2052  {
2053  maxfd = -1;
2054  FD_ZERO (&rfds);
2055  if ((0 == write_pout.size) && (1 == stdin_open))
2056  {
2057  FD_SET (STDIN_FILENO, &rfds);
2058  maxfd = MAX (maxfd, STDIN_FILENO);
2059  }
2060  if (0 == write_std.size)
2061  {
2062  FD_SET (dev.fd_raw, &rfds);
2063  maxfd = MAX (maxfd, dev.fd_raw);
2064  }
2065  FD_ZERO (&wfds);
2066  if (0 < write_std.size)
2067  {
2068  FD_SET (STDOUT_FILENO, &wfds);
2069  maxfd = MAX (maxfd, STDOUT_FILENO);
2070  }
2071  if (0 < write_pout.size)
2072  {
2073  FD_SET (dev.fd_raw, &wfds);
2074  maxfd = MAX (maxfd, dev.fd_raw);
2075  }
2076  {
2077  int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
2078  if ((-1 == retval) && (EINTR == errno))
2079  continue;
2080  if (0 > retval)
2081  {
2082  fprintf (stderr, "select failed: %s\n", strerror (errno));
2083  break;
2084  }
2085  }
2086  if (FD_ISSET (STDOUT_FILENO, &wfds))
2087  {
2088  ssize_t ret =
2089  write (STDOUT_FILENO, write_std.buf + write_std.pos,
2091  if (0 > ret)
2092  {
2093  fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
2094  break;
2095  }
2096  write_std.pos += ret;
2097  if (write_std.pos == write_std.size)
2098  {
2099  write_std.pos = 0;
2100  write_std.size = 0;
2101  }
2102  }
2103  if (FD_ISSET (dev.fd_raw, &wfds))
2104  {
2105  ssize_t ret =
2106  write (dev.fd_raw, write_pout.buf + write_pout.pos,
2108  if (0 > ret)
2109  {
2110  fprintf (stderr, "Failed to write to WLAN device: %s\n",
2111  strerror (errno));
2112  break;
2113  }
2114  write_pout.pos += ret;
2115  if ((write_pout.pos != write_pout.size) && (0 != ret))
2116  {
2117  /* we should not get partial sends with packet-oriented devices... */
2118  fprintf (stderr, "Write error, partial send: %u/%u\n",
2119  (unsigned int) write_pout.pos,
2120  (unsigned int) write_pout.size);
2121  break;
2122  }
2123  if (write_pout.pos == write_pout.size)
2124  {
2125  write_pout.pos = 0;
2126  write_pout.size = 0;
2127  }
2128  }
2129 
2130  if (FD_ISSET (STDIN_FILENO, &rfds))
2131  {
2132  ssize_t ret =
2133  read (STDIN_FILENO, readbuf, sizeof(readbuf));
2134  if (0 > ret)
2135  {
2136  fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
2137  break;
2138  }
2139  if (0 == ret)
2140  {
2141  /* stop reading... */
2142  stdin_open = 0;
2143  }
2144  mst_receive (stdin_mst, readbuf, ret);
2145  }
2146 
2147  if (FD_ISSET (dev.fd_raw, &rfds))
2148  {
2150  ssize_t ret;
2151 
2152  rrm = (struct
2154  ret =
2155  linux_read (&dev, (unsigned char *) &rrm->frame,
2156  sizeof(write_std.buf)
2157  - sizeof(struct
2159  + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2160  rrm);
2161  if (0 > ret)
2162  {
2163  fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2164  break;
2165  }
2166  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2167  {
2168  write_std.size = ret
2169  + sizeof(struct
2171  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2172  rrm->header.size = htons (write_std.size);
2173  rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2174  }
2175  }
2176  }
2177  /* Error handling, try to clean up a bit at least */
2178  mst_destroy (stdin_mst);
2179  (void) close (dev.fd_raw);
2180  return 1; /* we never exit 'normally' */
2181 }
2182 
2183 
2184 /* 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:487
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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#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:78
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:75
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.
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 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).
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:80
#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:77
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.