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
51 {
52 
57  size_t pos;
58 
63  size_t size;
64 
69  char buf[MAXLINE * 2];
70 };
71 
72 
76 static int closeprog;
77 
78 
84 static void
85 sigfunc (int sig)
86 {
87  closeprog = 1;
88  (void) unlink (FIFO_FILE1);
89  (void) unlink (FIFO_FILE2);
90 }
91 
92 
100 static int
102 {
103 
105 
106  GNUNET_memcpy (&macmsg.mac,
107  (char *) mac,
108  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
109  macmsg.hdr.size = htons (sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage));
111  GNUNET_memcpy (buffer,
112  &macmsg,
114  return sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage);
115 }
116 
117 
128 static int
129 stdin_send (void *cls,
130  const struct GNUNET_MessageHeader *hdr)
131 {
132  struct SendBuffer *write_pout = cls;
134  size_t payload_size;
136  uint16_t sendsize;
137 
138  sendsize = ntohs (hdr->size);
139  in = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
140  if ( (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ||
141  (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) > sendsize) )
142  {
143  FPRINTF (stderr, "%s", "Received malformed message\n");
144  exit (1);
145  }
146  payload_size = sendsize - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage);
147  if ((payload_size + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) + 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,
161  &in[1],
162  payload_size);
163  write_pout->size += payload_size;
164  return GNUNET_OK;
165 }
166 
167 
177 static int
178 file_in_send (void *cls,
179  const struct GNUNET_MessageHeader *hdr)
180 {
181  struct SendBuffer *write_std = cls;
182  uint16_t sendsize;
183 
184  sendsize = ntohs (hdr->size);
185  if ((sendsize + write_std->size) > MAXLINE * 2)
186  {
187  FPRINTF (stderr, "%s", "Packet too big for buffer\n");
188  exit (1);
189  }
190  GNUNET_memcpy (write_std->buf + write_std->size, hdr, sendsize);
191  write_std->size += sendsize;
192  return GNUNET_OK;
193 }
194 
195 
203 int
204 main (int argc, char *argv[])
205 {
206  struct stat st;
207  int erg;
208  FILE *fpin = NULL;
209  FILE *fpout = NULL;
210  int fdpin;
211  int fdpout;
212  char readbuf[MAXLINE];
213  int readsize;
214  struct SendBuffer write_std;
215  struct SendBuffer write_pout;
216  int ret;
217  int maxfd;
218  fd_set rfds;
219  fd_set wfds;
220  struct timeval tv;
221  int retval;
223  struct GNUNET_MessageStreamTokenizer *file_in_mst = NULL;
224  struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
225  int first;
226 
227  if ( (2 != argc) ||
228  ((0 != strcmp (argv[1], "1")) && (0 != strcmp (argv[1], "2"))) )
229  {
230  FPRINTF (stderr,
231  "%s",
232  "This program must be started with the operating mode (1 or 2) as the only argument.\n");
233  return 1;
234  }
235 
236  /* make the fifos if needed */
237  umask (0);
240  {
241  FPRINTF (stderr,
242  "Failed to create directory for file `%s'\n",
243  FIFO_FILE1);
244  return 1;
245  }
246  if (0 == strcmp (argv[1], "1") )
247  {
248  if (0 != stat (FIFO_FILE1, &st))
249  {
250  erg = mkfifo (FIFO_FILE1, 0666);
251  if ( (0 != erg) && (EEXIST != errno) )
252  FPRINTF (stderr, "Error in mkfifo(%s): %s\n", FIFO_FILE1,
253  strerror (errno));
254  }
255  }
256  else
257  {
258  if (0 != stat (FIFO_FILE2, &st))
259  {
260  GNUNET_break (0 == (erg = mkfifo (FIFO_FILE2, 0666)));
261  if ( (0 != erg) && (EEXIST != errno) )
262  FPRINTF (stderr,
263  "Error in mkfifo(%s): %s\n",
264  FIFO_FILE2,
265  strerror (errno));
266  }
267  }
268 
269  if (0 == strcmp (argv[1], "1"))
270  {
271  first = 1;
272  fpin = fopen (FIFO_FILE1, "r");
273  if (NULL == fpin)
274  {
275  FPRINTF (stderr,
276  "fopen of read FIFO_FILE1 failed: %s\n",
277  STRERROR (errno));
278  goto end;
279  }
280  if (NULL == (fpout = fopen (FIFO_FILE2, "w")))
281  {
282  GNUNET_break (0 == mkfifo (FIFO_FILE2, 0666));
283  fpout = fopen (FIFO_FILE2, "w");
284  }
285  if (NULL == fpout)
286  {
287  FPRINTF (stderr,
288  "fopen of write FIFO_FILE2 failed: %s\n",
289  STRERROR (errno));
290  goto end;
291  }
292  }
293  else
294  {
295  first = 0;
296  if (NULL == (fpout = fopen (FIFO_FILE1, "w")))
297  {
298  GNUNET_break (0 == mkfifo (FIFO_FILE1, 0666));
299  fpout = fopen (FIFO_FILE1, "w");
300  }
301  if (NULL == fpout)
302  {
303  FPRINTF (stderr,
304  "fopen of write FIFO_FILE1 failed: %s\n",
305  STRERROR (errno));
306  goto end;
307  }
308  fpin = fopen (FIFO_FILE2, "r");
309  if (NULL == fpin)
310  {
311  FPRINTF (stderr,
312  "fopen of read FIFO_FILE2 failed: %s\n",
313  STRERROR (errno));
314  goto end;
315  }
316  }
317 
318  fdpin = fileno (fpin);
319  GNUNET_assert (fpin >= 0);
320  if (fdpin >= FD_SETSIZE)
321  {
322  FPRINTF (stderr,
323  "File fdpin number too large (%d > %u)\n",
324  fdpin,
325  (unsigned int) FD_SETSIZE);
326  goto end;
327  }
328 
329  fdpout = fileno (fpout);
330  GNUNET_assert (fdpout >= 0);
331 
332  if (fdpout >= FD_SETSIZE)
333  {
334  FPRINTF (stderr,
335  "File fdpout number too large (%d > %u)\n",
336  fdpout,
337  (unsigned int) FD_SETSIZE);
338  goto end;
339  }
340 
341  signal (SIGINT, &sigfunc);
342  signal (SIGTERM, &sigfunc);
343  signal (GNUNET_TERM_SIG, &sigfunc);
344 
345  write_std.size = 0;
346  write_std.pos = 0;
347  write_pout.size = 0;
348  write_pout.pos = 0;
349  stdin_mst = GNUNET_MST_create (&stdin_send, &write_pout);
350  file_in_mst = GNUNET_MST_create (&file_in_send, &write_std);
351 
352  /* Send 'random' mac address */
353  macaddr.mac[0] = 0x13;
354  macaddr.mac[1] = 0x22;
355  macaddr.mac[2] = 0x33;
356  macaddr.mac[3] = 0x44;
359  write_std.size = send_mac_to_plugin (write_std.buf, &macaddr);
360 
361  while (0 == closeprog)
362  {
363  maxfd = -1;
364  tv.tv_sec = 5;
365  tv.tv_usec = 0;
366 
367  FD_ZERO (&rfds);
368  FD_ZERO (&wfds);
369  /* if output queue is empty, read */
370  if (0 == write_pout.size)
371  {
372  FD_SET (STDIN_FILENO, &rfds);
373  maxfd = MAX (STDIN_FILENO, maxfd);
374  }
375  if (0 == write_std.size)
376  {
377  FD_SET (fdpin, &rfds);
378  maxfd = MAX (fdpin, maxfd);
379  }
380 
381  /* if there is something to write, try to write */
382  if (0 < write_std.size)
383  {
384  FD_SET (STDOUT_FILENO, &wfds);
385  maxfd = MAX (maxfd, STDOUT_FILENO);
386  }
387  if (0 < write_pout.size)
388  {
389  FD_SET (fdpout, &wfds);
390  maxfd = MAX (maxfd, fdpout);
391  }
392 
393  retval = select (maxfd + 1, &rfds, &wfds, NULL, &tv);
394  if ((-1 == retval) && (EINTR == errno))
395  continue;
396  if (0 > retval)
397  {
398  FPRINTF (stderr, "select failed: %s\n", STRERROR (errno));
399  closeprog = 1;
400  break;
401  }
402 
403  if (FD_ISSET (STDOUT_FILENO, &wfds))
404  {
405  ret =
406  write (STDOUT_FILENO, write_std.buf + write_std.pos,
407  write_std.size - write_std.pos);
408  if (0 > ret)
409  {
410  closeprog = 1;
411  FPRINTF (stderr, "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 =
430  write (fdpout, 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, "Write ERROR to fdpout failed: %s\n", STRERROR (errno));
437  }
438  else
439  {
440  write_pout.pos += ret;
441  /* check if finished writing */
442  if (write_pout.pos == write_pout.size)
443  {
444  write_pout.pos = 0;
445  write_pout.size = 0;
446  }
447  }
448  }
449 
450  if (FD_ISSET (STDIN_FILENO, &rfds))
451  {
452  readsize = read (STDIN_FILENO, readbuf, sizeof (readbuf));
453 
454  if (0 > readsize)
455  {
456  closeprog = 1;
457  FPRINTF (stderr, "Error reading from STDIN_FILENO: %s\n",
458  STRERROR (errno));
459  }
460  else if (0 < readsize)
461  {
462  GNUNET_MST_from_buffer (stdin_mst,
463  readbuf, readsize,
465 
466  }
467  else
468  {
469  /* eof */
470  closeprog = 1;
471  }
472  }
473 
474  if (FD_ISSET (fdpin, &rfds))
475  {
476  readsize = read (fdpin, readbuf, sizeof (readbuf));
477  if (0 > readsize)
478  {
479  closeprog = 1;
480  FPRINTF (stderr, "Error reading from fdpin: %s\n", STRERROR (errno));
481  break;
482  }
483  else if (0 < readsize)
484  {
485  GNUNET_MST_from_buffer (file_in_mst,
486  readbuf, readsize,
488  }
489  else
490  {
491  /* eof */
492  closeprog = 1;
493  }
494  }
495  }
496 
497 end:
498  /* clean up */
499  if (NULL != stdin_mst)
500  GNUNET_MST_destroy (stdin_mst);
501  if (NULL != file_in_mst)
502  GNUNET_MST_destroy (file_in_mst);
503 
504  if (NULL != fpout)
505  fclose (fpout);
506  if (NULL != fpin)
507  fclose (fpin);
508  if (1 == first)
509  {
510  (void) unlink (FIFO_FILE1);
511  (void) unlink (FIFO_FILE2);
512  }
513  return 0;
514 }
#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.
#define FPRINTF
Definition: plibc.h:683
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.
#define STRERROR(i)
Definition: plibc.h:676
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER&#39;.
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:833
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
#define FD_SETSIZE
Definition: winproc.h:39
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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:413
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:87
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:116
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:282
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.