GNUnet  0.20.0
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
51 {
56  size_t pos;
57 
62  size_t size;
63 
68  char buf[MAXLINE * 2];
69 };
70 
71 
75 static int closeprog;
76 
77 
83 static void
84 sigfunc (int sig)
85 {
86  closeprog = 1;
87  (void) unlink (FIFO_FILE1);
88  (void) unlink (FIFO_FILE2);
89 }
90 
91 
99 static int
101 {
103 
104  GNUNET_memcpy (&macmsg.mac,
105  (char *) mac,
106  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
107  macmsg.hdr.size =
108  htons (sizeof(struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
110  GNUNET_memcpy (buffer,
111  &macmsg,
113  return sizeof(struct GNUNET_TRANSPORT_WLAN_HelperControlMessage);
114 }
115 
116 
127 static int
128 stdin_send (void *cls, const struct GNUNET_MessageHeader *hdr)
129 {
130  struct SendBuffer *write_pout = cls;
132  size_t payload_size;
134  uint16_t sendsize;
135 
136  sendsize = ntohs (hdr->size);
137  in = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
138  if ((GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ||
139  (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) > sendsize))
140  {
141  fprintf (stderr, "%s", "Received malformed message\n");
142  exit (1);
143  }
144  payload_size =
145  sendsize - sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage);
146  if ((payload_size
148  + write_pout->size) > MAXLINE * 2)
149  {
150  fprintf (stderr, "%s", "Packet too big for buffer\n");
151  exit (1);
152  }
153  memset (&newheader, 0, sizeof(newheader));
154  newheader.header.size = htons (payload_size + sizeof(newheader));
156  newheader.frame = in->frame;
158  &newheader,
159  sizeof(newheader));
160  write_pout->size += sizeof(newheader);
161  GNUNET_memcpy (write_pout->buf + write_pout->size, &in[1], payload_size);
162  write_pout->size += payload_size;
163  return GNUNET_OK;
164 }
165 
166 
176 static int
177 file_in_send (void *cls, const struct GNUNET_MessageHeader *hdr)
178 {
179  struct SendBuffer *write_std = cls;
180  uint16_t sendsize;
181 
182  sendsize = ntohs (hdr->size);
183  if ((sendsize + write_std->size) > MAXLINE * 2)
184  {
185  fprintf (stderr, "%s", "Packet too big for buffer\n");
186  exit (1);
187  }
188  GNUNET_memcpy (write_std->buf + write_std->size, hdr, sendsize);
189  write_std->size += sendsize;
190  return GNUNET_OK;
191 }
192 
193 
201 int
202 main (int argc, char *argv[])
203 {
204  struct stat st;
205  int erg;
206  FILE *fpin = NULL;
207  FILE *fpout = NULL;
208  int fdpin;
209  int fdpout;
210  char readbuf[MAXLINE];
211  int readsize;
212  struct SendBuffer write_std;
213  struct SendBuffer write_pout;
214  int ret;
215  int maxfd;
216  fd_set rfds;
217  fd_set wfds;
218  struct timeval tv;
219  int retval;
221  struct GNUNET_MessageStreamTokenizer *file_in_mst = NULL;
222  struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
223  int first;
224 
225  if ((2 != argc) ||
226  ((0 != strcmp (argv[1], "1")) && (0 != strcmp (argv[1], "2"))))
227  {
228  fprintf (
229  stderr,
230  "%s",
231  "This program must be started with the operating mode (1 or 2) as the only argument.\n");
232  return 1;
233  }
234 
235  /* make the fifos if needed */
236  umask (0);
239  {
240  fprintf (stderr, "Failed to create directory for file `%s'\n", FIFO_FILE1);
241  return 1;
242  }
243  if (0 == strcmp (argv[1], "1"))
244  {
245  if (0 != stat (FIFO_FILE1, &st))
246  {
247  erg = mkfifo (FIFO_FILE1, 0666);
248  if ((0 != erg) && (EEXIST != errno))
249  fprintf (stderr,
250  "Error in mkfifo(%s): %s\n",
251  FIFO_FILE1,
252  strerror (errno));
253  }
254  }
255  else
256  {
257  if (0 != stat (FIFO_FILE2, &st))
258  {
259  GNUNET_break (0 == (erg = mkfifo (FIFO_FILE2, 0666)));
260  if ((0 != erg) && (EEXIST != errno))
261  fprintf (stderr,
262  "Error in mkfifo(%s): %s\n",
263  FIFO_FILE2,
264  strerror (errno));
265  }
266  }
267 
268  if (0 == strcmp (argv[1], "1"))
269  {
270  first = 1;
271  fpin = fopen (FIFO_FILE1, "r");
272  if (NULL == fpin)
273  {
274  fprintf (stderr,
275  "fopen of read FIFO_FILE1 failed: %s\n",
276  strerror (errno));
277  goto end;
278  }
279  if (NULL == (fpout = fopen (FIFO_FILE2, "w")))
280  {
281  GNUNET_break (0 == mkfifo (FIFO_FILE2, 0666));
282  fpout = fopen (FIFO_FILE2, "w");
283  }
284  if (NULL == fpout)
285  {
286  fprintf (stderr,
287  "fopen of write FIFO_FILE2 failed: %s\n",
288  strerror (errno));
289  goto end;
290  }
291  }
292  else
293  {
294  first = 0;
295  if (NULL == (fpout = fopen (FIFO_FILE1, "w")))
296  {
297  GNUNET_break (0 == mkfifo (FIFO_FILE1, 0666));
298  fpout = fopen (FIFO_FILE1, "w");
299  }
300  if (NULL == fpout)
301  {
302  fprintf (stderr,
303  "fopen of write FIFO_FILE1 failed: %s\n",
304  strerror (errno));
305  goto end;
306  }
307  fpin = fopen (FIFO_FILE2, "r");
308  if (NULL == fpin)
309  {
310  fprintf (stderr,
311  "fopen of read FIFO_FILE2 failed: %s\n",
312  strerror (errno));
313  goto end;
314  }
315  }
316 
317  fdpin = fileno (fpin);
318  GNUNET_assert (fpin >= 0);
319  if (fdpin >= FD_SETSIZE)
320  {
321  fprintf (stderr,
322  "File fdpin number too large (%d > %u)\n",
323  fdpin,
324  (unsigned int) FD_SETSIZE);
325  goto end;
326  }
327 
328  fdpout = fileno (fpout);
329  GNUNET_assert (fdpout >= 0);
330 
331  if (fdpout >= FD_SETSIZE)
332  {
333  fprintf (stderr,
334  "File fdpout number too large (%d > %u)\n",
335  fdpout,
336  (unsigned int) FD_SETSIZE);
337  goto end;
338  }
339 
340  signal (SIGINT, &sigfunc);
341  signal (SIGTERM, &sigfunc);
342  signal (GNUNET_TERM_SIG, &sigfunc);
343 
344  write_std.size = 0;
345  write_std.pos = 0;
346  write_pout.size = 0;
347  write_pout.pos = 0;
349  file_in_mst = GNUNET_MST_create (&file_in_send, &write_std);
350 
351  /* Send 'random' mac address */
352  macaddr.mac[0] = 0x13;
353  macaddr.mac[1] = 0x22;
354  macaddr.mac[2] = 0x33;
355  macaddr.mac[3] = 0x44;
359 
360  while (0 == closeprog)
361  {
362  maxfd = -1;
363  tv.tv_sec = 5;
364  tv.tv_usec = 0;
365 
366  FD_ZERO (&rfds);
367  FD_ZERO (&wfds);
368  /* if output queue is empty, read */
369  if (0 == write_pout.size)
370  {
371  FD_SET (STDIN_FILENO, &rfds);
372  maxfd = MAX (STDIN_FILENO, maxfd);
373  }
374  if (0 == write_std.size)
375  {
376  FD_SET (fdpin, &rfds);
377  maxfd = MAX (fdpin, maxfd);
378  }
379 
380  /* if there is something to write, try to write */
381  if (0 < write_std.size)
382  {
383  FD_SET (STDOUT_FILENO, &wfds);
384  maxfd = MAX (maxfd, STDOUT_FILENO);
385  }
386  if (0 < write_pout.size)
387  {
388  FD_SET (fdpout, &wfds);
389  maxfd = MAX (maxfd, fdpout);
390  }
391 
392  retval = select (maxfd + 1, &rfds, &wfds, NULL, &tv);
393  if ((-1 == retval) && (EINTR == errno))
394  continue;
395  if (0 > retval)
396  {
397  fprintf (stderr, "select failed: %s\n", strerror (errno));
398  closeprog = 1;
399  break;
400  }
401 
402  if (FD_ISSET (STDOUT_FILENO, &wfds))
403  {
404  ret = write (STDOUT_FILENO,
407  if (0 > ret)
408  {
409  closeprog = 1;
410  fprintf (stderr,
411  "Write ERROR to STDOUT_FILENO: %s\n",
412  strerror (errno));
413  break;
414  }
415  else
416  {
417  write_std.pos += ret;
418  /* check if finished writing */
419  if (write_std.pos == write_std.size)
420  {
421  write_std.pos = 0;
422  write_std.size = 0;
423  }
424  }
425  }
426 
427  if (FD_ISSET (fdpout, &wfds))
428  {
429  ret = write (fdpout,
432 
433  if (0 > ret)
434  {
435  closeprog = 1;
436  fprintf (stderr,
437  "Write ERROR to fdpout failed: %s\n",
438  strerror (errno));
439  }
440  else
441  {
442  write_pout.pos += ret;
443  /* check if finished writing */
444  if (write_pout.pos == write_pout.size)
445  {
446  write_pout.pos = 0;
447  write_pout.size = 0;
448  }
449  }
450  }
451 
452  if (FD_ISSET (STDIN_FILENO, &rfds))
453  {
454  readsize = read (STDIN_FILENO, readbuf, sizeof(readbuf));
455 
456  if (0 > readsize)
457  {
458  closeprog = 1;
459  fprintf (stderr,
460  "Error reading from STDIN_FILENO: %s\n",
461  strerror (errno));
462  }
463  else if (0 < readsize)
464  {
466  readbuf,
467  readsize,
468  GNUNET_NO,
469  GNUNET_NO);
470  }
471  else
472  {
473  /* eof */
474  closeprog = 1;
475  }
476  }
477 
478  if (FD_ISSET (fdpin, &rfds))
479  {
480  readsize = read (fdpin, readbuf, sizeof(readbuf));
481  if (0 > readsize)
482  {
483  closeprog = 1;
484  fprintf (stderr, "Error reading from fdpin: %s\n", strerror (errno));
485  break;
486  }
487  else if (0 < readsize)
488  {
489  GNUNET_MST_from_buffer (file_in_mst,
490  readbuf,
491  readsize,
492  GNUNET_NO,
493  GNUNET_NO);
494  }
495  else
496  {
497  /* eof */
498  closeprog = 1;
499  }
500  }
501  }
502 
503 end:
504  /* clean up */
505  if (NULL != stdin_mst)
507  if (NULL != file_in_mst)
508  GNUNET_MST_destroy (file_in_mst);
509 
510  if (NULL != fpout)
511  fclose (fpout);
512  if (NULL != fpin)
513  fclose (fpin);
514  if (1 == first)
515  {
516  (void) unlink (FIFO_FILE1);
517  (void) unlink (FIFO_FILE2);
518  }
519  return 0;
520 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
static struct SendBuffer write_std
Buffer for data read from the bluetooth device to be transmitted to stdout.
static struct SendBuffer write_pout
Buffer for data read from stdin to be transmitted to the bluetooth device.
int main(int argc, char *argv[])
Main function of a program that pretends to be a WLAN card.
static int closeprog
Flag set to 1 if we are to terminate, otherwise 0.
static int file_in_send(void *cls, const struct GNUNET_MessageHeader *hdr)
We read a full message from stdin.
static int send_mac_to_plugin(char *buffer, struct GNUNET_TRANSPORT_WLAN_MacAddress *mac)
Create control message for plugin.
#define FIFO_FILE1
Name of the fifo to use for IPC with the other dummy process.
#define MAXLINE
Maximum size of a message allowed in either direction (used for our receive and sent buffers).
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 ...
#define FIFO_FILE2
Name of the fifo to use for IPC with the other dummy process.
static void sigfunc(int sig)
We're being killed, clean up.
Constants for network protocols.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER
Type of data messages from the plugin to the gnunet-wlan-helper.
#define GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL
Control message between the gnunet-wlan-helper and the daemon (with the MAC).
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER
Type of data messages from the gnunet-wlan-helper to the plugin.
enum GNUNET_GenericReturnValue 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:101
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition: mst.c:404
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition: mst.c:86
#define GNUNET_TERM_SIG
The termination signal.
Definition: platform.h:234
header for transport plugin and the helper for wlan
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle to a message stream tokenizer.
Definition: mst.c:45
struct GNUNET_MessageHeader hdr
Message header.
struct GNUNET_TRANSPORT_WLAN_MacAddress mac
MAC Address of the local WLAN interface.
Message from the WLAN helper to the plugin: we have received the given message with the given perform...
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
struct GNUNET_MessageHeader header
Type is 'GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER'.
Message from the plugin to the WLAN helper: send the given message with the given connection paramete...
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...
IO buffer used for buffering data in transit (to wireless or to stdout).
size_t pos
How many bytes that were stored in 'buf' did we already write to the destination? Always smaller than...
size_t size
How many bytes of data are stored in 'buf' for transmission right now? Data always starts at offset 0...
char buf[4096 *2]
Buffered data; twice the maximum allowed message size as we add some headers.