GNUnet  0.10.x
gnunet-helper-transport-wlan-dummy.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010, 2012 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
25 #include "platform.h"
26 #include "gnunet_protocols.h"
27 #include "gnunet_util_lib.h"
28 #include "plugin_transport_wlan.h"
29 
33 #define FIFO_FILE1 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_in"
34 
38 #define FIFO_FILE2 "/tmp/test-transport/api-wlan-p1/WLAN_FIFO_out"
39 
44 #define MAXLINE 4096
45 
46 
50 struct SendBuffer {
55  size_t pos;
56 
61  size_t size;
62 
67  char buf[MAXLINE * 2];
68 };
69 
70 
74 static int closeprog;
75 
76 
82 static void
83 sigfunc(int sig)
84 {
85  closeprog = 1;
86  (void)unlink(FIFO_FILE1);
87  (void)unlink(FIFO_FILE2);
88 }
89 
90 
98 static int
100 {
102 
103  GNUNET_memcpy(&macmsg.mac,
104  (char *)mac,
105  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
106  macmsg.hdr.size =
107  htons(sizeof(struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
109  GNUNET_memcpy(buffer,
110  &macmsg,
112  return sizeof(struct GNUNET_TRANSPORT_WLAN_HelperControlMessage);
113 }
114 
115 
126 static int
127 stdin_send(void *cls, const struct GNUNET_MessageHeader *hdr)
128 {
129  struct SendBuffer *write_pout = cls;
131  size_t payload_size;
133  uint16_t sendsize;
134 
135  sendsize = ntohs(hdr->size);
136  in = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *)hdr;
137  if ((GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs(hdr->type)) ||
138  (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) > sendsize))
139  {
140  fprintf(stderr, "%s", "Received malformed message\n");
141  exit(1);
142  }
143  payload_size =
144  sendsize - sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage);
145  if ((payload_size +
147  write_pout->size) > MAXLINE * 2)
148  {
149  fprintf(stderr, "%s", "Packet too big for buffer\n");
150  exit(1);
151  }
152  memset(&newheader, 0, sizeof(newheader));
153  newheader.header.size = htons(payload_size + sizeof(newheader));
155  newheader.frame = in->frame;
156  GNUNET_memcpy(write_pout->buf + write_pout->size,
157  &newheader,
158  sizeof(newheader));
159  write_pout->size += sizeof(newheader);
160  GNUNET_memcpy(write_pout->buf + write_pout->size, &in[1], payload_size);
161  write_pout->size += payload_size;
162  return GNUNET_OK;
163 }
164 
165 
175 static int
176 file_in_send(void *cls, const struct GNUNET_MessageHeader *hdr)
177 {
178  struct SendBuffer *write_std = cls;
179  uint16_t sendsize;
180 
181  sendsize = ntohs(hdr->size);
182  if ((sendsize + write_std->size) > MAXLINE * 2)
183  {
184  fprintf(stderr, "%s", "Packet too big for buffer\n");
185  exit(1);
186  }
187  GNUNET_memcpy(write_std->buf + write_std->size, hdr, sendsize);
188  write_std->size += sendsize;
189  return GNUNET_OK;
190 }
191 
192 
200 int
201 main(int argc, char *argv[])
202 {
203  struct stat st;
204  int erg;
205  FILE *fpin = NULL;
206  FILE *fpout = NULL;
207  int fdpin;
208  int fdpout;
209  char readbuf[MAXLINE];
210  int readsize;
211  struct SendBuffer write_std;
212  struct SendBuffer write_pout;
213  int ret;
214  int maxfd;
215  fd_set rfds;
216  fd_set wfds;
217  struct timeval tv;
218  int retval;
220  struct GNUNET_MessageStreamTokenizer *file_in_mst = NULL;
221  struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
222  int first;
223 
224  if ((2 != argc) ||
225  ((0 != strcmp(argv[1], "1")) && (0 != strcmp(argv[1], "2"))))
226  {
227  fprintf(
228  stderr,
229  "%s",
230  "This program must be started with the operating mode (1 or 2) as the only argument.\n");
231  return 1;
232  }
233 
234  /* make the fifos if needed */
235  umask(0);
238  {
239  fprintf(stderr, "Failed to create directory for file `%s'\n", FIFO_FILE1);
240  return 1;
241  }
242  if (0 == strcmp(argv[1], "1"))
243  {
244  if (0 != stat(FIFO_FILE1, &st))
245  {
246  erg = mkfifo(FIFO_FILE1, 0666);
247  if ((0 != erg) && (EEXIST != errno))
248  fprintf(stderr,
249  "Error in mkfifo(%s): %s\n",
250  FIFO_FILE1,
251  strerror(errno));
252  }
253  }
254  else
255  {
256  if (0 != stat(FIFO_FILE2, &st))
257  {
258  GNUNET_break(0 == (erg = mkfifo(FIFO_FILE2, 0666)));
259  if ((0 != erg) && (EEXIST != errno))
260  fprintf(stderr,
261  "Error in mkfifo(%s): %s\n",
262  FIFO_FILE2,
263  strerror(errno));
264  }
265  }
266 
267  if (0 == strcmp(argv[1], "1"))
268  {
269  first = 1;
270  fpin = fopen(FIFO_FILE1, "r");
271  if (NULL == fpin)
272  {
273  fprintf(stderr,
274  "fopen of read FIFO_FILE1 failed: %s\n",
275  strerror(errno));
276  goto end;
277  }
278  if (NULL == (fpout = fopen(FIFO_FILE2, "w")))
279  {
280  GNUNET_break(0 == mkfifo(FIFO_FILE2, 0666));
281  fpout = fopen(FIFO_FILE2, "w");
282  }
283  if (NULL == fpout)
284  {
285  fprintf(stderr,
286  "fopen of write FIFO_FILE2 failed: %s\n",
287  strerror(errno));
288  goto end;
289  }
290  }
291  else
292  {
293  first = 0;
294  if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
295  {
296  GNUNET_break(0 == mkfifo(FIFO_FILE1, 0666));
297  fpout = fopen(FIFO_FILE1, "w");
298  }
299  if (NULL == fpout)
300  {
301  fprintf(stderr,
302  "fopen of write FIFO_FILE1 failed: %s\n",
303  strerror(errno));
304  goto end;
305  }
306  fpin = fopen(FIFO_FILE2, "r");
307  if (NULL == fpin)
308  {
309  fprintf(stderr,
310  "fopen of read FIFO_FILE2 failed: %s\n",
311  strerror(errno));
312  goto end;
313  }
314  }
315 
316  fdpin = fileno(fpin);
317  GNUNET_assert(fpin >= 0);
318  if (fdpin >= FD_SETSIZE)
319  {
320  fprintf(stderr,
321  "File fdpin number too large (%d > %u)\n",
322  fdpin,
323  (unsigned int)FD_SETSIZE);
324  goto end;
325  }
326 
327  fdpout = fileno(fpout);
328  GNUNET_assert(fdpout >= 0);
329 
330  if (fdpout >= FD_SETSIZE)
331  {
332  fprintf(stderr,
333  "File fdpout number too large (%d > %u)\n",
334  fdpout,
335  (unsigned int)FD_SETSIZE);
336  goto end;
337  }
338 
339  signal(SIGINT, &sigfunc);
340  signal(SIGTERM, &sigfunc);
341  signal(GNUNET_TERM_SIG, &sigfunc);
342 
343  write_std.size = 0;
344  write_std.pos = 0;
345  write_pout.size = 0;
346  write_pout.pos = 0;
347  stdin_mst = GNUNET_MST_create(&stdin_send, &write_pout);
348  file_in_mst = GNUNET_MST_create(&file_in_send, &write_std);
349 
350  /* Send 'random' mac address */
351  macaddr.mac[0] = 0x13;
352  macaddr.mac[1] = 0x22;
353  macaddr.mac[2] = 0x33;
354  macaddr.mac[3] = 0x44;
357  write_std.size = send_mac_to_plugin(write_std.buf, &macaddr);
358 
359  while (0 == closeprog)
360  {
361  maxfd = -1;
362  tv.tv_sec = 5;
363  tv.tv_usec = 0;
364 
365  FD_ZERO(&rfds);
366  FD_ZERO(&wfds);
367  /* if output queue is empty, read */
368  if (0 == write_pout.size)
369  {
370  FD_SET(STDIN_FILENO, &rfds);
371  maxfd = MAX(STDIN_FILENO, maxfd);
372  }
373  if (0 == write_std.size)
374  {
375  FD_SET(fdpin, &rfds);
376  maxfd = MAX(fdpin, maxfd);
377  }
378 
379  /* if there is something to write, try to write */
380  if (0 < write_std.size)
381  {
382  FD_SET(STDOUT_FILENO, &wfds);
383  maxfd = MAX(maxfd, STDOUT_FILENO);
384  }
385  if (0 < write_pout.size)
386  {
387  FD_SET(fdpout, &wfds);
388  maxfd = MAX(maxfd, fdpout);
389  }
390 
391  retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
392  if ((-1 == retval) && (EINTR == errno))
393  continue;
394  if (0 > retval)
395  {
396  fprintf(stderr, "select failed: %s\n", strerror(errno));
397  closeprog = 1;
398  break;
399  }
400 
401  if (FD_ISSET(STDOUT_FILENO, &wfds))
402  {
403  ret = write(STDOUT_FILENO,
404  write_std.buf + write_std.pos,
405  write_std.size - write_std.pos);
406  if (0 > ret)
407  {
408  closeprog = 1;
409  fprintf(stderr,
410  "Write ERROR to STDOUT_FILENO: %s\n",
411  strerror(errno));
412  break;
413  }
414  else
415  {
416  write_std.pos += ret;
417  /* check if finished writing */
418  if (write_std.pos == write_std.size)
419  {
420  write_std.pos = 0;
421  write_std.size = 0;
422  }
423  }
424  }
425 
426  if (FD_ISSET(fdpout, &wfds))
427  {
428  ret = write(fdpout,
429  write_pout.buf + write_pout.pos,
430  write_pout.size - write_pout.pos);
431 
432  if (0 > ret)
433  {
434  closeprog = 1;
435  fprintf(stderr,
436  "Write ERROR to fdpout failed: %s\n",
437  strerror(errno));
438  }
439  else
440  {
441  write_pout.pos += ret;
442  /* check if finished writing */
443  if (write_pout.pos == write_pout.size)
444  {
445  write_pout.pos = 0;
446  write_pout.size = 0;
447  }
448  }
449  }
450 
451  if (FD_ISSET(STDIN_FILENO, &rfds))
452  {
453  readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
454 
455  if (0 > readsize)
456  {
457  closeprog = 1;
458  fprintf(stderr,
459  "Error reading from STDIN_FILENO: %s\n",
460  strerror(errno));
461  }
462  else if (0 < readsize)
463  {
464  GNUNET_MST_from_buffer(stdin_mst,
465  readbuf,
466  readsize,
467  GNUNET_NO,
468  GNUNET_NO);
469  }
470  else
471  {
472  /* eof */
473  closeprog = 1;
474  }
475  }
476 
477  if (FD_ISSET(fdpin, &rfds))
478  {
479  readsize = read(fdpin, readbuf, sizeof(readbuf));
480  if (0 > readsize)
481  {
482  closeprog = 1;
483  fprintf(stderr, "Error reading from fdpin: %s\n", strerror(errno));
484  break;
485  }
486  else if (0 < readsize)
487  {
488  GNUNET_MST_from_buffer(file_in_mst,
489  readbuf,
490  readsize,
491  GNUNET_NO,
492  GNUNET_NO);
493  }
494  else
495  {
496  /* eof */
497  closeprog = 1;
498  }
499  }
500  }
501 
502 end:
503  /* clean up */
504  if (NULL != stdin_mst)
505  GNUNET_MST_destroy(stdin_mst);
506  if (NULL != file_in_mst)
507  GNUNET_MST_destroy(file_in_mst);
508 
509  if (NULL != fpout)
510  fclose(fpout);
511  if (NULL != fpin)
512  fclose(fpin);
513  if (1 == first)
514  {
515  (void)unlink(FIFO_FILE1);
516  (void)unlink(FIFO_FILE2);
517  }
518  return 0;
519 }
#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).
static struct SendBuffer write_pout
Buffer for data read from stdin to be transmitted to the bluetooth device.
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct GNUNET_MessageHeader hdr
Message header.
static struct SendBuffer write_std
Buffer for data read from the bluetooth device to be transmitted to stdout.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER&#39;.
#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.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:681
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int main(int argc, char *argv[])
Main function of a program that pretends to be a WLAN card.
Format of a WLAN Control Message.
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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
size_t size
How many bytes of data are stored in &#39;buf&#39; for transmission right now? Data always starts at offset 0...
static void sigfunc(int sig)
We&#39;re being killed, clean up.
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:410
Handle to a message stream tokenizer.
Definition: mst.c:43
Randomness for IVs etc.
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:84
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
int GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition: mst.c:113
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...
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER
Type of data messages from the plugin to the gnunet-wlan-helper.
static int file_in_send(void *cls, const struct GNUNET_MessageHeader *hdr)
We read a full message from stdin.
#define MAXLINE
Maximum size of a message allowed in either direction (used for our receive and sent buffers)...
char buf[4096 *2]
Buffered data; twice the maximum allowed message size as we add some headers.
static int closeprog
Flag set to 1 if we are to terminate, otherwise 0.
static int stdin_send(void *cls, const struct GNUNET_MessageHeader *hdr)
We got a message from the FIFO, check it, convert the message type to the output forward and copy it ...
header for transport plugin and the helper for wlan
#define FIFO_FILE1
Name of the fifo to use for IPC with the other dummy process.
Header for all communications.
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER
Type of data messages from the gnunet-wlan-helper to the plugin.
#define FIFO_FILE2
Name of the fifo to use for IPC with the other dummy process.
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:242
Message from the plugin to the WLAN helper: send the given message with the given connection paramete...
size_t pos
How many bytes that were stored in &#39;buf&#39; did we already write to the destination? Always smaller than...
static int send_mac_to_plugin(char *buffer, struct GNUNET_TRANSPORT_WLAN_MacAddress *mac)
Create control message for plugin.
High-quality operations are desired.