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 
237 struct PrismValue {
242  uint32_t did;
243 
247  uint16_t status;
248 
254  uint16_t len;
255 
259  uint32_t data;
260 } __attribute__ ((packed));
261 
262 
266 struct PrismHeader {
270  uint32_t msgcode;
271 
275  uint32_t msglen;
276 
281 
282  /* followed by 'struct PrismValue's. Documentation suggests that these
283  are typically the hosttime, mactime, channel, rssi, sq, signal, noise,
284  rate, istx and frmlen values, but documentation is sparse. So we
285  will use the 'did' fields to find out what we actually got. */
286 } __attribute__ ((packed));
287 
288 
289 /* ****** end of structure of messages of type ARPHRD_IEEE80211_PRISM ******* */
290 
291 /* ********** structure of messages of type ARPHRD_IEEE80211_FULL *********** */
292 
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 
465 
474 #define IEEE80211_RADIOTAP_F_CFP 0x01
475 
484 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02
485 
494 #define IEEE80211_RADIOTAP_F_WEP 0x04
495 
504 #define IEEE80211_RADIOTAP_F_FRAG 0x08
505 
514 #define IEEE80211_RADIOTAP_F_FCS 0x10
515 
525 #define IEEE80211_RADIOTAP_F_DATAPAD 0x20
526 
527 
532 #define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001
533 
538 #define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001
539 
544 #define IEEE80211_RADIOTAP_F_TX_CTS 0x0002
545 
550 #define IEEE80211_RADIOTAP_F_TX_RTS 0x0004
551 
556 #define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008
557 
562 #define IEEE80211_RADIOTAP_F_TX_NOSEQ 0x0010
563 
564 
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 
615  struct Ieee80211RadiotapHeader header;
616 
620  uint8_t rate;
621 
628  uint8_t pad1;
629 
633  uint16_t txflags;
634 };
635 
641 #define IEEE80211_RADIOTAP_OUR_TRANSMISSION_HEADER_MASK ((1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_TX_FLAGS))
642 
643 
644 
654 
658  const uint8_t *this_arg;
659 
663  const uint8_t *arg;
664 
668  const uint32_t *next_bitmap;
669 
673  size_t max_length;
674 
679  uint32_t bitmap_shifter;
680 
684  unsigned int this_arg_index;
685 
689  unsigned int arg_index;
690 };
691 
692 
693 /* ************** end of structure of ARPHRD_IEEE80211_FULL ************** */
694 
695 /* ************************** our globals ******************************* */
696 
701 struct HardwareInfos {
705  int fd_raw;
706 
712 
716  char iface[IFNAMSIZ];
717 
721  struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
722 };
723 
724 
728 struct SendBuffer {
733  size_t size;
734 
739  size_t pos;
740 
745  char buf[MAXLINE * 2];
746 };
747 
748 
752 static struct SendBuffer write_pout;
753 
757 static struct SendBuffer write_std;
758 
759 
760 
761 /* *********** specialized version of server_mst.c begins here ********** */
762 
767 #define ALIGN_FACTOR 8
768 
772 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
773 
774 
782 typedef void (*MessageTokenizerCallback) (void *cls,
783  const struct
785  message);
786 
790 struct MessageStreamTokenizer {
795 
799  void *cb_cls;
800 
804  size_t curr_buf;
805 
809  size_t off;
810 
814  size_t pos;
815 
819  struct GNUNET_MessageHeader *hdr;
820 };
821 
822 
830 static struct MessageStreamTokenizer *
832  void *cb_cls)
833 {
834  struct MessageStreamTokenizer *ret;
835 
836  ret = malloc(sizeof(struct MessageStreamTokenizer));
837  if (NULL == ret)
838  {
839  fprintf(stderr, "Failed to allocate buffer for tokenizer\n");
840  exit(1);
841  }
842  ret->hdr = malloc(MIN_BUFFER_SIZE);
843  if (NULL == ret->hdr)
844  {
845  fprintf(stderr, "Failed to allocate buffer for alignment\n");
846  exit(1);
847  }
848  ret->curr_buf = MIN_BUFFER_SIZE;
849  ret->cb = cb;
850  ret->cb_cls = cb_cls;
851  return ret;
852 }
853 
854 
865 static int
867  const char *buf, size_t size)
868 {
869  const struct GNUNET_MessageHeader *hdr;
870  size_t delta;
871  uint16_t want;
872  char *ibuf;
873  int need_align;
874  unsigned long offset;
875  int ret;
876 
877  ret = GNUNET_OK;
878  ibuf = (char *)mst->hdr;
879  while (mst->pos > 0)
880  {
881 do_align:
882  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
883  (0 != (mst->off % ALIGN_FACTOR)))
884  {
885  /* need to align or need more space */
886  mst->pos -= mst->off;
887  memmove(ibuf, &ibuf[mst->off], mst->pos);
888  mst->off = 0;
889  }
890  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
891  {
892  delta =
893  GNUNET_MIN(sizeof(struct GNUNET_MessageHeader) -
894  (mst->pos - mst->off), size);
895  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
896  mst->pos += delta;
897  buf += delta;
898  size -= delta;
899  }
900  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
901  {
902  return GNUNET_OK;
903  }
904  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
905  want = ntohs(hdr->size);
906  if (want < sizeof(struct GNUNET_MessageHeader))
907  {
908  fprintf(stderr,
909  "Received invalid message from stdin\n");
910  exit(1);
911  }
912  if (mst->curr_buf - mst->off < want)
913  {
914  /* need more space */
915  mst->pos -= mst->off;
916  memmove(ibuf, &ibuf[mst->off], mst->pos);
917  mst->off = 0;
918  }
919  if (want > mst->curr_buf)
920  {
921  mst->hdr = realloc(mst->hdr, want);
922  if (NULL == mst->hdr)
923  {
924  fprintf(stderr, "Failed to allocate buffer for alignment\n");
925  exit(1);
926  }
927  ibuf = (char *)mst->hdr;
928  mst->curr_buf = want;
929  }
930  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
931  if (mst->pos - mst->off < want)
932  {
933  delta = GNUNET_MIN(want - (mst->pos - mst->off), size);
934  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
935  mst->pos += delta;
936  buf += delta;
937  size -= delta;
938  }
939  if (mst->pos - mst->off < want)
940  {
941  return GNUNET_OK;
942  }
943  mst->cb(mst->cb_cls, hdr);
944  mst->off += want;
945  if (mst->off == mst->pos)
946  {
947  /* reset to beginning of buffer, it's free right now! */
948  mst->off = 0;
949  mst->pos = 0;
950  }
951  }
952  while (size > 0)
953  {
954  if (size < sizeof(struct GNUNET_MessageHeader))
955  break;
956  offset = (unsigned long)buf;
957  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
958  if (GNUNET_NO == need_align)
959  {
960  /* can try to do zero-copy and process directly from original buffer */
961  hdr = (const struct GNUNET_MessageHeader *)buf;
962  want = ntohs(hdr->size);
963  if (want < sizeof(struct GNUNET_MessageHeader))
964  {
965  fprintf(stderr,
966  "Received invalid message from stdin\n");
967  exit(1);
968  }
969  if (size < want)
970  break; /* or not, buffer incomplete, so copy to private buffer... */
971  mst->cb(mst->cb_cls, hdr);
972  buf += want;
973  size -= want;
974  }
975  else
976  {
977  /* need to copy to private buffer to align;
978  * yes, we go a bit more spagetti than usual here */
979  goto do_align;
980  }
981  }
982  if (size > 0)
983  {
984  if (size + mst->pos > mst->curr_buf)
985  {
986  mst->hdr = realloc(mst->hdr, size + mst->pos);
987  if (NULL == mst->hdr)
988  {
989  fprintf(stderr, "Failed to allocate buffer for alignment\n");
990  exit(1);
991  }
992  ibuf = (char *)mst->hdr;
993  mst->curr_buf = size + mst->pos;
994  }
995  if (mst->pos + size > mst->curr_buf)
996  {
997  fprintf(stderr,
998  "Assertion failed\n");
999  exit(1);
1000  }
1001  GNUNET_memcpy(&ibuf[mst->pos], buf, size);
1002  mst->pos += size;
1003  }
1004  return ret;
1005 }
1006 
1007 
1013 static void
1015 {
1016  free(mst->hdr);
1017  free(mst);
1018 }
1019 
1020 /* ***************** end of server_mst.c clone ***************** **/
1021 
1022 
1023 /* ************** code for handling of ARPHRD_IEEE80211_FULL ************** */
1024 
1042 static int
1044  const struct Ieee80211RadiotapHeader *radiotap_header,
1045  size_t max_length)
1046 {
1047  if ((iterator == NULL) ||
1048  (radiotap_header == NULL))
1049  return -1;
1050 
1051  /* Linux only supports version 0 radiotap format */
1052  if (0 != radiotap_header->it_version)
1053  return -1;
1054 
1055  /* sanity check for allowed length and radiotap length field */
1056  if ((max_length < sizeof(struct Ieee80211RadiotapHeader)) ||
1057  (max_length < (GNUNET_le16toh(radiotap_header->it_len))))
1058  return -1;
1059 
1060  memset(iterator, 0, sizeof(struct Ieee80211RadiotapHeaderIterator));
1061  iterator->rtheader = radiotap_header;
1062  iterator->max_length = GNUNET_le16toh(radiotap_header->it_len);
1063  iterator->bitmap_shifter = GNUNET_le32toh(radiotap_header->it_present);
1064  iterator->arg = ((uint8_t *)radiotap_header) + sizeof(struct Ieee80211RadiotapHeader);
1065 
1066  /* find payload start allowing for extended bitmap(s) */
1068  {
1069  while (GNUNET_le32toh(*((uint32_t *)iterator->arg)) & IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
1070  {
1071  iterator->arg += sizeof(uint32_t);
1072  /*
1073  * check for insanity where the present bitmaps
1074  * keep claiming to extend up to or even beyond the
1075  * stated radiotap header length
1076  */
1077  if (iterator->arg - ((uint8_t*)iterator->rtheader) > iterator->max_length)
1078  return -1;
1079  }
1080  iterator->arg += sizeof(uint32_t);
1081  /*
1082  * no need to check again for blowing past stated radiotap
1083  * header length, becuase ieee80211_radiotap_iterator_next
1084  * checks it before it is dereferenced
1085  */
1086  }
1087  /* we are all initialized happily */
1088  return 0;
1089 }
1090 
1091 
1104 static int
1106 {
1107  /*
1108  * small length lookup table for all radiotap types we heard of
1109  * starting from b0 in the bitmap, so we can walk the payload
1110  * area of the radiotap header
1111  *
1112  * There is a requirement to pad args, so that args
1113  * of a given length must begin at a boundary of that length
1114  * -- but note that compound args are allowed (eg, 2 x uint16_t
1115  * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
1116  * a reliable indicator of alignment requirement.
1117  *
1118  * upper nybble: content alignment for arg
1119  * lower nybble: content length for arg
1120  */
1121 
1122  static const uint8_t rt_sizes[] = {
1123  [IEEE80211_RADIOTAP_TSFT] = 0x88,
1124  [IEEE80211_RADIOTAP_FLAGS] = 0x11,
1125  [IEEE80211_RADIOTAP_RATE] = 0x11,
1126  [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
1127  [IEEE80211_RADIOTAP_FHSS] = 0x22,
1134  [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
1137  [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
1138  [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
1141  /*
1142  * add more here as they are defined in
1143  * include/net/ieee80211_radiotap.h
1144  */
1145  };
1146 
1147  /*
1148  * for every radiotap entry we can at
1149  * least skip (by knowing the length)...
1150  */
1151  while (iterator->arg_index < sizeof(rt_sizes))
1152  {
1153  int hit = (0 != (iterator->bitmap_shifter & 1));
1154 
1155  if (hit)
1156  {
1157  unsigned int wanted_alignment;
1158  unsigned int unalignment;
1159  /*
1160  * arg is present, account for alignment padding
1161  * 8-bit args can be at any alignment
1162  * 16-bit args must start on 16-bit boundary
1163  * 32-bit args must start on 32-bit boundary
1164  * 64-bit args must start on 64-bit boundary
1165  *
1166  * note that total arg size can differ from alignment of
1167  * elements inside arg, so we use upper nybble of length table
1168  * to base alignment on. First, 'wanted_alignment' is set to be
1169  * 1 for 8-bit, 2 for 16-bit, 4 for 32-bit and 8 for 64-bit
1170  * arguments. Then, we calculate the 'unalignment' (how many
1171  * bytes we are over by taking the difference of 'arg' and the
1172  * overall starting point modulo the desired alignment. As
1173  * desired alignments are powers of two, we can do modulo with
1174  * binary "&" (and also avoid the possibility of a division by
1175  * zero if the 'rt_sizes' table contains bogus entries).
1176  *
1177  * also note: these alignments are relative to the start of the
1178  * radiotap header. There is no guarantee that the radiotap
1179  * header itself is aligned on any kind of boundary, thus we
1180  * need to really look at the delta here.
1181  */
1182  wanted_alignment = rt_sizes[iterator->arg_index] >> 4;
1183  unalignment = (((void *)iterator->arg) - ((void *)iterator->rtheader)) & (wanted_alignment - 1);
1184  if (0 != unalignment)
1185  {
1186  /* need padding (by 'wanted_alignment - unalignment') */
1187  iterator->arg_index += wanted_alignment - unalignment;
1188  }
1189 
1190  /*
1191  * this is what we will return to user, but we need to
1192  * move on first so next call has something fresh to test
1193  */
1194  iterator->this_arg_index = iterator->arg_index;
1195  iterator->this_arg = iterator->arg;
1196 
1197  /* internally move on the size of this arg (using lower nybble from
1198  the table) */
1199  iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
1200 
1201  /*
1202  * check for insanity where we are given a bitmap that
1203  * claims to have more arg content than the length of the
1204  * radiotap section. We will normally end up equalling this
1205  * max_length on the last arg, never exceeding it.
1206  */
1207  if ((((void *)iterator->arg) - ((void *)iterator->rtheader)) > iterator->max_length)
1208  return -1;
1209  }
1210 
1211  /* Now, move on to next bit / next entry */
1212  iterator->arg_index++;
1213 
1214  if (0 == (iterator->arg_index % 32))
1215  {
1216  /* completed current uint32_t bitmap */
1217  if (0 != (iterator->bitmap_shifter & 1))
1218  {
1219  /* bit 31 was set, there is more; move to next uint32_t bitmap */
1220  iterator->bitmap_shifter = GNUNET_le32toh(*iterator->next_bitmap);
1221  iterator->next_bitmap++;
1222  }
1223  else
1224  {
1225  /* no more bitmaps: end (by setting arg_index to high, unsupported value) */
1226  iterator->arg_index = sizeof(rt_sizes);
1227  }
1228  }
1229  else
1230  {
1231  /* just try the next bit (while loop will move on) */
1232  iterator->bitmap_shifter >>= 1;
1233  }
1234 
1235  /* if we found a valid arg earlier, return it now */
1236  if (hit)
1237  return iterator->this_arg_index;
1238  }
1239 
1240  /* we don't know how to handle any more args (or there are no more),
1241  so we're done (this is not an error) */
1242  return -1;
1243 }
1244 
1245 
1253 static unsigned long
1254 calc_crc_osdep(const unsigned char *buf, size_t len)
1255 {
1256  static const unsigned long int crc_tbl_osdep[256] = {
1257  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1258  0xE963A535, 0x9E6495A3,
1259  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
1260  0xE7B82D07, 0x90BF1D91,
1261  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
1262  0xF4D4B551, 0x83D385C7,
1263  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1264  0xFA0F3D63, 0x8D080DF5,
1265  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
1266  0xD20D85FD, 0xA50AB56B,
1267  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
1268  0xDCD60DCF, 0xABD13D59,
1269  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1270  0xCFBA9599, 0xB8BDA50F,
1271  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
1272  0xC1611DAB, 0xB6662D3D,
1273  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
1274  0x9FBFE4A5, 0xE8B8D433,
1275  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1276  0x91646C97, 0xE6635C01,
1277  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
1278  0x8208F4C1, 0xF50FC457,
1279  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
1280  0x8CD37CF3, 0xFBD44C65,
1281  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1282  0xA4D1C46D, 0xD3D6F4FB,
1283  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
1284  0xAA0A4C5F, 0xDD0D7CC9,
1285  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
1286  0xB966D409, 0xCE61E49F,
1287  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1288  0xB7BD5C3B, 0xC0BA6CAD,
1289  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
1290  0x04DB2615, 0x73DC1683,
1291  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
1292  0x0A00AE27, 0x7D079EB1,
1293  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1294  0x196C3671, 0x6E6B06E7,
1295  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
1296  0x17B7BE43, 0x60B08ED5,
1297  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
1298  0x3FB506DD, 0x48B2364B,
1299  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1300  0x316E8EEF, 0x4669BE79,
1301  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
1302  0x220216B9, 0x5505262F,
1303  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
1304  0x2CD99E8B, 0x5BDEAE1D,
1305  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1306  0x72076785, 0x05005713,
1307  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
1308  0x7CDCEFB7, 0x0BDBDF21,
1309  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
1310  0x6FB077E1, 0x18B74777,
1311  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1312  0x616BFFD3, 0x166CCF45,
1313  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
1314  0x4969474D, 0x3E6E77DB,
1315  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
1316  0x47B2CF7F, 0x30B5FFE9,
1317  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1318  0x54DE5729, 0x23D967BF,
1319  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
1320  0x5A05DF1B, 0x2D02EF8D
1321  };
1322 
1323  unsigned long crc = 0xFFFFFFFF;
1324 
1325  for (; len > 0; len--, buf++)
1326  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
1327  return(~crc);
1328 }
1329 
1330 
1339 static int
1340 check_crc_buf_osdep(const unsigned char *buf, size_t len)
1341 {
1342  unsigned long crc;
1343 
1344  crc = calc_crc_osdep(buf, len);
1345  buf += len;
1346  if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
1347  ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
1348  return 0;
1349  return 1;
1350 }
1351 
1352 
1353 /* ************end of code for handling of ARPHRD_IEEE80211_FULL ************** */
1354 
1355 
1356 /* ************beginning of code for reading packets from kernel ************** */
1357 
1364 static int
1365 get_channel_from_frequency(int32_t frequency)
1366 {
1367  if (frequency >= 2412 && frequency <= 2472)
1368  return (frequency - 2407) / 5;
1369  if (frequency == 2484)
1370  return 14;
1371  if (frequency >= 5000 && frequency <= 6100)
1372  return (frequency - 5000) / 5;
1373  return -1;
1374 }
1375 
1376 
1383 static int
1385 {
1386  struct iwreq wrq;
1387  int32_t frequency;
1388 
1389  memset(&wrq, 0, sizeof(struct iwreq));
1390  strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ);
1391  if (0 > ioctl(dev->fd_raw, SIOCGIWFREQ, &wrq))
1392  return -1;
1393  frequency = wrq.u.freq.m; /* 'iw_freq' defines 'm' as '__s32', so we keep it signed */
1394  if (100000000 < frequency)
1395  frequency /= 100000;
1396  else if (1000000 < frequency)
1397  frequency /= 1000;
1398  if (1000 < frequency)
1399  return get_channel_from_frequency(frequency);
1400  return frequency;
1401 }
1402 
1403 
1415 static ssize_t
1417  unsigned char *buf, size_t buf_size,
1419 {
1420  unsigned char tmpbuf[buf_size];
1421  ssize_t caplen;
1422  size_t n;
1423  int got_signal = 0;
1424  int got_noise = 0;
1425  int got_channel = 0;
1426  int fcs_removed = 0;
1427 
1428  caplen = read(dev->fd_raw, tmpbuf, buf_size);
1429  if (0 > caplen)
1430  {
1431  if (EAGAIN == errno)
1432  return 0;
1433  fprintf(stderr, "Failed to read from RAW socket: %s\n", strerror(errno));
1434  return -1;
1435  }
1436 
1437  memset(ri, 0, sizeof(*ri));
1438  switch (dev->arptype_in)
1439  {
1441  {
1442  const struct PrismHeader *ph;
1443 
1444  ph = (const struct PrismHeader*)tmpbuf;
1445  n = ph->msglen;
1446  if ((n < 8) || (n >= caplen))
1447  return 0; /* invalid format */
1448  if ((PRISM_MSGCODE_MONITOR == ph->msgcode) &&
1449  (n >= sizeof(struct PrismHeader)))
1450  {
1451  const char *pos;
1452  size_t left;
1453  struct PrismValue pv;
1454 
1455  left = n - sizeof(struct PrismHeader);
1456  pos = (const char *)&ph[1];
1457  while (left > sizeof(struct PrismValue))
1458  {
1459  left -= sizeof(struct PrismValue);
1460  GNUNET_memcpy(&pv, pos, sizeof(struct PrismValue));
1461  pos += sizeof(struct PrismValue);
1462 
1463  switch (pv.did)
1464  {
1465  case PRISM_DID_NOISE:
1466  if (PRISM_STATUS_OK == pv.status)
1467  {
1468  ri->ri_noise = pv.data;
1469  /* got_noise = 1; */
1470  }
1471  break;
1472 
1473  case PRISM_DID_RATE:
1474  if (PRISM_STATUS_OK == pv.status)
1475  ri->ri_rate = pv.data * 500000;
1476  break;
1477 
1478  case PRISM_DID_CHANNEL:
1479  if (PRISM_STATUS_OK == pv.status)
1480  {
1481  ri->ri_channel = pv.data;
1482  got_channel = 1;
1483  }
1484  break;
1485 
1486  case PRISM_DID_MACTIME:
1487  if (PRISM_STATUS_OK == pv.status)
1488  ri->ri_mactime = pv.data;
1489  break;
1490 
1491  case PRISM_DID_SIGNAL:
1492  if (PRISM_STATUS_OK == pv.status)
1493  {
1494  ri->ri_power = pv.data;
1495  /* got_signal = 1; */
1496  }
1497  break;
1498  }
1499  }
1500  }
1501  if ((n < 8) || (n >= caplen))
1502  return 0; /* invalid format */
1503  }
1504  break;
1505 
1506  case ARPHRD_IEEE80211_FULL:
1507  {
1508  struct Ieee80211RadiotapHeaderIterator iterator;
1509  struct Ieee80211RadiotapHeader *rthdr;
1510 
1511  memset(&iterator, 0, sizeof(iterator));
1512  rthdr = (struct Ieee80211RadiotapHeader *)tmpbuf;
1513  n = GNUNET_le16toh(rthdr->it_len);
1514  if ((n < sizeof(struct Ieee80211RadiotapHeader)) || (n >= caplen))
1515  return 0; /* invalid 'it_len' */
1516  if (0 != ieee80211_radiotap_iterator_init(&iterator, rthdr, caplen))
1517  return 0;
1518  /* go through the radiotap arguments we have been given by the driver */
1519  while (0 <= ieee80211_radiotap_iterator_next(&iterator))
1520  {
1521  switch (iterator.this_arg_index)
1522  {
1524  ri->ri_mactime = GNUNET_le64toh(*((uint64_t *)iterator.this_arg));
1525  break;
1526 
1528  if (!got_signal)
1529  {
1530  ri->ri_power = *((int8_t*)iterator.this_arg);
1531  got_signal = 1;
1532  }
1533  break;
1534 
1536  if (!got_signal)
1537  {
1538  ri->ri_power = *((int8_t*)iterator.this_arg);
1539  got_signal = 1;
1540  }
1541  break;
1542 
1544  if (!got_noise)
1545  {
1546  ri->ri_noise = *((int8_t*)iterator.this_arg);
1547  got_noise = 1;
1548  }
1549  break;
1550 
1552  if (!got_noise)
1553  {
1554  ri->ri_noise = *((int8_t*)iterator.this_arg);
1555  got_noise = 1;
1556  }
1557  break;
1558 
1560  ri->ri_antenna = *iterator.this_arg;
1561  break;
1562 
1564  ri->ri_channel = *iterator.this_arg;
1565  got_channel = 1;
1566  break;
1567 
1569  ri->ri_rate = (*iterator.this_arg) * 500000;
1570  break;
1571 
1573  {
1574  uint8_t flags = *iterator.this_arg;
1575  /* is the CRC visible at the end? if so, remove */
1576  if (0 != (flags & IEEE80211_RADIOTAP_F_FCS))
1577  {
1578  fcs_removed = 1;
1579  caplen -= sizeof(uint32_t);
1580  }
1581  break;
1582  }
1583 
1585  {
1586  uint16_t flags = ntohs(*((uint16_t *)iterator.this_arg));
1587  if (0 != (flags & IEEE80211_RADIOTAP_F_RX_BADFCS))
1588  return 0;
1589  }
1590  break;
1591  } /* end of 'switch' */
1592  } /* end of the 'while' loop */
1593  }
1594  break;
1595 
1596  case ARPHRD_IEEE80211:
1597  n = 0; /* no header */
1598  break;
1599 
1600  case ARPHRD_ETHER:
1601  {
1602  if (sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) > caplen)
1603  return 0; /* invalid */
1605  tmpbuf + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame),
1606  caplen - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4 /* 4 byte FCS */);
1607  return caplen - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame) - 4;
1608  }
1609 
1610  default:
1611  errno = ENOTSUP; /* unsupported format */
1612  return -1;
1613  }
1614  caplen -= n;
1615  if (!got_channel)
1616  ri->ri_channel = linux_get_channel(dev);
1617 
1618  /* detect CRC32 at the end, even if the flag wasn't set and remove it */
1619  if ((0 == fcs_removed) &&
1620  (0 == check_crc_buf_osdep(tmpbuf + n, caplen - sizeof(uint32_t))))
1621  {
1622  /* NOTE: this heuristic can of course fail if there happens to
1623  be a matching checksum at the end. Would be good to have
1624  some data to see how often this heuristic actually works. */
1625  caplen -= sizeof(uint32_t);
1626  }
1627  /* copy payload to target buffer */
1628  GNUNET_memcpy(buf, tmpbuf + n, caplen);
1629  return caplen;
1630 }
1631 
1632 
1633 /* ************end of code for reading packets from kernel ************** */
1634 
1635 /* ************other helper functions for main start here ************** */
1636 
1637 
1644 static int
1646 {
1647  struct ifreq ifr;
1648  struct iwreq wrq;
1649  struct packet_mreq mr;
1650  struct sockaddr_ll sll;
1651 
1652  /* find the interface index */
1653  memset(&ifr, 0, sizeof(ifr));
1654  strncpy(ifr.ifr_name, dev->iface, IFNAMSIZ);
1655  if (-1 == ioctl(dev->fd_raw, SIOCGIFINDEX, &ifr))
1656  {
1657  fprintf(stderr, "ioctl(SIOCGIFINDEX) on interface `%.*s' failed: %s\n",
1658  IFNAMSIZ, dev->iface, strerror(errno));
1659  return 1;
1660  }
1661 
1662  /* lookup the hardware type */
1663  memset(&sll, 0, sizeof(sll));
1664  sll.sll_family = AF_PACKET;
1665  sll.sll_ifindex = ifr.ifr_ifindex;
1666  sll.sll_protocol = htons(ETH_P_ALL);
1667  if (-1 == ioctl(dev->fd_raw, SIOCGIFHWADDR, &ifr))
1668  {
1669  fprintf(stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1670  IFNAMSIZ, dev->iface, strerror(errno));
1671  return 1;
1672  }
1673  if (((ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1674  (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1675  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1676  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL)))
1677  {
1678  fprintf(stderr, "Error: interface `%.*s' is not using a supported hardware address family (got %d)\n",
1679  IFNAMSIZ, dev->iface,
1680  ifr.ifr_hwaddr.sa_family);
1681  return 1;
1682  }
1683 
1684  /* lookup iw mode */
1685  memset(&wrq, 0, sizeof(struct iwreq));
1686  strncpy(wrq.ifr_name, dev->iface, IFNAMSIZ);
1687  if (-1 == ioctl(dev->fd_raw, SIOCGIWMODE, &wrq))
1688  {
1689  /* most probably not supported (ie for rtap ipw interface) *
1690  * so just assume its correctly set... */
1691  wrq.u.mode = IW_MODE_MONITOR;
1692  }
1693 
1694  if ((wrq.u.mode != IW_MODE_MONITOR) &&
1695  (wrq.u.mode != IW_MODE_ADHOC))
1696  {
1697  fprintf(stderr, "Error: interface `%.*s' is not in monitor or ad-hoc mode (got %d)\n",
1698  IFNAMSIZ, dev->iface,
1699  wrq.u.mode);
1700  return 1;
1701  }
1702 
1703  /* Is interface st to up, broadcast & running ? */
1704  if ((ifr.ifr_flags | IFF_UP | IFF_BROADCAST | IFF_RUNNING) != ifr.ifr_flags)
1705  {
1706  /* Bring interface up */
1707  ifr.ifr_flags |= IFF_UP | IFF_BROADCAST | IFF_RUNNING;
1708 
1709  if (-1 == ioctl(dev->fd_raw, SIOCSIFFLAGS, &ifr))
1710  {
1711  fprintf(stderr, "ioctl(SIOCSIFFLAGS) on interface `%.*s' failed: %s\n",
1712  IFNAMSIZ, dev->iface, strerror(errno));
1713  return 1;
1714  }
1715  }
1716 
1717  /* bind the raw socket to the interface */
1718  if (-1 == bind(dev->fd_raw, (struct sockaddr *)&sll, sizeof(sll)))
1719  {
1720  fprintf(stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1721  dev->iface, strerror(errno));
1722  return 1;
1723  }
1724 
1725  /* lookup the hardware type */
1726  if (-1 == ioctl(dev->fd_raw, SIOCGIFHWADDR, &ifr))
1727  {
1728  fprintf(stderr, "ioctl(SIOCGIFHWADDR) on interface `%.*s' failed: %s\n",
1729  IFNAMSIZ, dev->iface, strerror(errno));
1730  return 1;
1731  }
1732 
1733  GNUNET_memcpy(&dev->pl_mac, ifr.ifr_hwaddr.sa_data, MAC_ADDR_SIZE);
1734  dev->arptype_in = ifr.ifr_hwaddr.sa_family;
1735  if ((ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) &&
1736  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211) &&
1737  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_PRISM) &&
1738  (ifr.ifr_hwaddr.sa_family != ARPHRD_IEEE80211_FULL))
1739  {
1740  fprintf(stderr, "Unsupported hardware link type %d on interface `%.*s'\n",
1741  ifr.ifr_hwaddr.sa_family, IFNAMSIZ, dev->iface);
1742  return 1;
1743  }
1744 
1745  /* enable promiscuous mode */
1746  memset(&mr, 0, sizeof(mr));
1747  mr.mr_ifindex = sll.sll_ifindex;
1748  mr.mr_type = PACKET_MR_PROMISC;
1749  if (0 !=
1750  setsockopt(dev->fd_raw, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
1751  sizeof(mr)))
1752  {
1753  fprintf(stderr,
1754  "Failed to enable promiscuous mode on interface `%.*s'\n",
1755  IFNAMSIZ,
1756  dev->iface);
1757  return 1;
1758  }
1759  return 0;
1760 }
1761 
1762 
1770 static int
1771 test_wlan_interface(const char *iface)
1772 {
1773  char strbuf[512];
1774  struct stat sbuf;
1775  int ret;
1776 
1777  ret = snprintf(strbuf, sizeof(strbuf),
1778  "/sys/class/net/%s/phy80211/subsystem",
1779  iface);
1780  if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat(strbuf, &sbuf)))
1781  {
1782  fprintf(stderr,
1783  "Did not find 802.11 interface `%s'. Exiting.\n",
1784  iface);
1785  exit(1);
1786  }
1787  return 0;
1788 }
1789 
1790 
1798 static int
1800  const struct HardwareInfos *dev)
1801 {
1802  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1803 
1804  if ((0 == memcmp(&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1805  (0 == memcmp(&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1806  return 0; /* some drivers set no Macs, then assume it is all for us! */
1807 
1808  if (0 != memcmp(&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1809  return 1; /* not a GNUnet ad-hoc package */
1810  if ((0 == memcmp(&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1811  (0 == memcmp(&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1812  return 0; /* for us, or broadcast */
1813  return 1; /* not for us */
1814 }
1815 
1816 
1823 static void
1825  const struct HardwareInfos *dev)
1826 {
1827  taIeeeHeader->frame_control = htons(IEEE80211_FC0_TYPE_DATA);
1828  taIeeeHeader->addr2 = dev->pl_mac;
1829  taIeeeHeader->addr3 = mac_bssid_gnunet;
1830 }
1831 
1832 
1841 static void
1842 stdin_send_hw(void *cls, const struct GNUNET_MessageHeader *hdr)
1843 {
1844  struct HardwareInfos *dev = cls;
1846  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *wlanheader;
1847  size_t sendsize;
1848  struct RadiotapTransmissionHeader rtheader;
1849  struct GNUNET_TRANSPORT_WLAN_Ieee8023Frame etheader;
1850 
1851  sendsize = ntohs(hdr->size);
1852  if ((sendsize <
1855  {
1856  fprintf(stderr, "Received malformed message\n");
1857  exit(1);
1858  }
1859  sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1860  if (MAXLINE < sendsize)
1861  {
1862  fprintf(stderr, "Packet too big for buffer\n");
1863  exit(1);
1864  }
1865  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *)hdr;
1866  switch (dev->arptype_in)
1867  {
1869  case ARPHRD_IEEE80211_FULL:
1870  case ARPHRD_IEEE80211:
1871  rtheader.header.it_version = 0;
1872  rtheader.header.it_pad = 0;
1873  rtheader.header.it_len = GNUNET_htole16(sizeof(rtheader));
1875  rtheader.rate = header->rate;
1876  rtheader.pad1 = 0;
1878  GNUNET_memcpy(write_pout.buf, &rtheader, sizeof(rtheader));
1879  GNUNET_memcpy(&write_pout.buf[sizeof(rtheader)], &header->frame, sendsize);
1880  wlanheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *)&write_pout.buf[sizeof(rtheader)];
1881 
1882  /* payload contains MAC address, but we don't trust it, so we'll
1883  * overwrite it with OUR MAC address to prevent mischief */
1884  mac_set(wlanheader, dev);
1885  write_pout.size = sendsize + sizeof(rtheader);
1886  break;
1887 
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 
1898  default:
1899  fprintf(stderr,
1900  "Unsupported ARPTYPE!\n");
1901  break;
1902  }
1903 }
1904 
1905 
1916 int
1917 main(int argc, char *argv[])
1918 {
1919  struct HardwareInfos dev;
1920  char readbuf[MAXLINE];
1921  int maxfd;
1922  fd_set rfds;
1923  fd_set wfds;
1924  int stdin_open;
1926  int raw_eno;
1927 
1928  /* assert privs so we can modify the firewall rules! */
1929  {
1930 #ifdef HAVE_SETRESUID
1931  uid_t uid = getuid();
1932 
1933  if (0 != setresuid(uid, 0, 0))
1934  {
1935  fprintf(stderr,
1936  "Failed to setresuid to root: %s\n",
1937  strerror(errno));
1938  return 254;
1939  }
1940 #else
1941  if (0 != seteuid(0))
1942  {
1943  fprintf(stderr,
1944  "Failed to seteuid back to root: %s\n", strerror(errno));
1945  return 254;
1946  }
1947 #endif
1948  }
1949 
1950  /* make use of SGID capabilities on POSIX */
1951  memset(&dev, 0, sizeof(dev));
1952  dev.fd_raw = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1953  raw_eno = errno; /* remember for later */
1954 
1955  /* now that we've dropped root rights, we can do error checking */
1956  if (2 != argc)
1957  {
1958  fprintf(stderr,
1959  "You must specify the name of the interface as the first and only argument to this program.\n");
1960  if (-1 != dev.fd_raw)
1961  (void)close(dev.fd_raw);
1962  return 1;
1963  }
1964 
1965  if (-1 == dev.fd_raw)
1966  {
1967  fprintf(stderr, "Failed to create raw socket: %s\n", strerror(raw_eno));
1968  return 1;
1969  }
1970  if (dev.fd_raw >= FD_SETSIZE)
1971  {
1972  fprintf(stderr, "File descriptor too large for select (%d > %d)\n",
1973  dev.fd_raw, FD_SETSIZE);
1974  (void)close(dev.fd_raw);
1975  return 1;
1976  }
1977  if (0 != test_wlan_interface(argv[1]))
1978  {
1979  (void)close(dev.fd_raw);
1980  return 1;
1981  }
1982  strncpy(dev.iface, argv[1], IFNAMSIZ);
1983  if (0 != open_device_raw(&dev))
1984  {
1985  (void)close(dev.fd_raw);
1986  return 1;
1987  }
1988 
1989  /* drop privs */
1990  {
1991  uid_t uid = getuid();
1992 #ifdef HAVE_SETRESUID
1993  if (0 != setresuid(uid, uid, uid))
1994  {
1995  fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1996  if (-1 != dev.fd_raw)
1997  (void)close(dev.fd_raw);
1998  return 1;
1999  }
2000 #else
2001  if (0 != (setuid(uid) | seteuid(uid)))
2002  {
2003  fprintf(stderr, "Failed to setuid: %s\n", strerror(errno));
2004  if (-1 != dev.fd_raw)
2005  (void)close(dev.fd_raw);
2006  return 1;
2007  }
2008 #endif
2009  }
2010 
2011 
2012  /* send MAC address of the WLAN interface to STDOUT first */
2013  {
2015 
2016  macmsg.hdr.size = htons(sizeof(macmsg));
2018  GNUNET_memcpy(&macmsg.mac, &dev.pl_mac, sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
2019  GNUNET_memcpy(write_std.buf, &macmsg, sizeof(macmsg));
2020  write_std.size = sizeof(macmsg);
2021  }
2022 
2023  stdin_mst = mst_create(&stdin_send_hw, &dev);
2024  stdin_open = 1;
2025  while (1)
2026  {
2027  maxfd = -1;
2028  FD_ZERO(&rfds);
2029  if ((0 == write_pout.size) && (1 == stdin_open))
2030  {
2031  FD_SET(STDIN_FILENO, &rfds);
2032  maxfd = MAX(maxfd, STDIN_FILENO);
2033  }
2034  if (0 == write_std.size)
2035  {
2036  FD_SET(dev.fd_raw, &rfds);
2037  maxfd = MAX(maxfd, dev.fd_raw);
2038  }
2039  FD_ZERO(&wfds);
2040  if (0 < write_std.size)
2041  {
2042  FD_SET(STDOUT_FILENO, &wfds);
2043  maxfd = MAX(maxfd, STDOUT_FILENO);
2044  }
2045  if (0 < write_pout.size)
2046  {
2047  FD_SET(dev.fd_raw, &wfds);
2048  maxfd = MAX(maxfd, dev.fd_raw);
2049  }
2050  {
2051  int retval = select(maxfd + 1, &rfds, &wfds, NULL, NULL);
2052  if ((-1 == retval) && (EINTR == errno))
2053  continue;
2054  if (0 > retval)
2055  {
2056  fprintf(stderr, "select failed: %s\n", strerror(errno));
2057  break;
2058  }
2059  }
2060  if (FD_ISSET(STDOUT_FILENO, &wfds))
2061  {
2062  ssize_t ret =
2063  write(STDOUT_FILENO, write_std.buf + write_std.pos,
2065  if (0 > ret)
2066  {
2067  fprintf(stderr, "Failed to write to STDOUT: %s\n", strerror(errno));
2068  break;
2069  }
2070  write_std.pos += ret;
2071  if (write_std.pos == write_std.size)
2072  {
2073  write_std.pos = 0;
2074  write_std.size = 0;
2075  }
2076  }
2077  if (FD_ISSET(dev.fd_raw, &wfds))
2078  {
2079  ssize_t ret =
2080  write(dev.fd_raw, write_pout.buf + write_pout.pos,
2082  if (0 > ret)
2083  {
2084  fprintf(stderr, "Failed to write to WLAN device: %s\n",
2085  strerror(errno));
2086  break;
2087  }
2088  write_pout.pos += ret;
2089  if ((write_pout.pos != write_pout.size) && (0 != ret))
2090  {
2091  /* we should not get partial sends with packet-oriented devices... */
2092  fprintf(stderr, "Write error, partial send: %u/%u\n",
2093  (unsigned int)write_pout.pos,
2094  (unsigned int)write_pout.size);
2095  break;
2096  }
2097  if (write_pout.pos == write_pout.size)
2098  {
2099  write_pout.pos = 0;
2100  write_pout.size = 0;
2101  }
2102  }
2103 
2104  if (FD_ISSET(STDIN_FILENO, &rfds))
2105  {
2106  ssize_t ret =
2107  read(STDIN_FILENO, readbuf, sizeof(readbuf));
2108  if (0 > ret)
2109  {
2110  fprintf(stderr, "Read error from STDIN: %s\n", strerror(errno));
2111  break;
2112  }
2113  if (0 == ret)
2114  {
2115  /* stop reading... */
2116  stdin_open = 0;
2117  }
2118  mst_receive(stdin_mst, readbuf, ret);
2119  }
2120 
2121  if (FD_ISSET(dev.fd_raw, &rfds))
2122  {
2124  ssize_t ret;
2125 
2127  ret =
2128  linux_read(&dev, (unsigned char *)&rrm->frame,
2129  sizeof(write_std.buf)
2131  + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2132  rrm);
2133  if (0 > ret)
2134  {
2135  fprintf(stderr, "Read error from raw socket: %s\n", strerror(errno));
2136  break;
2137  }
2138  if ((0 < ret) && (0 == mac_test(&rrm->frame, &dev)))
2139  {
2140  write_std.size = ret
2142  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2143  rrm->header.size = htons(write_std.size);
2144  rrm->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2145  }
2146  }
2147  }
2148  /* Error handling, try to clean up a bit at least */
2149  mst_destroy(stdin_mst);
2150  (void)close(dev.fd_raw);
2151  return 1; /* we never exit 'normally' */
2152 }
2153 
2154 /* 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:480
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.
#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.
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 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:66
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.