GNUnet  0.11.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
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;
157  GNUNET_memcpy (write_pout->buf + write_pout->size,
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;
348  stdin_mst = GNUNET_MST_create (&stdin_send, &write_pout);
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;
358  write_std.size = send_mac_to_plugin (write_std.buf, &macaddr);
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,
405  write_std.buf + write_std.pos,
406  write_std.size - write_std.pos);
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,
430  write_pout.buf + write_pout.pos,
431  write_pout.size - write_pout.pos);
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  {
465  GNUNET_MST_from_buffer (stdin_mst,
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)
506  GNUNET_MST_destroy (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 }
#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.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
#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...
#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:411
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:85
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:114
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.