GNUnet  0.11.x
gnunet-helper-exit.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010, 2011, 2012 Christian Grothoff
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  */
20 
44 #include "platform.h"
45 
46 #ifdef IF_TUN_HDR
47 #include IF_TUN_HDR
48 #endif
49 
50 #if defined(BSD) || defined(SOLARIS)
51 #define ifr_netmask ifr_ifru.ifru_addr
52 #define SIOGIFINDEX SIOCGIFINDEX
53 #endif
54 
58 #include "gnunet_crypto_lib.h"
59 #include "gnunet_common.h"
60 
64 #include "gnunet_protocols.h"
65 
70 #define DEBUG GNUNET_NO
71 
75 #define MAX_SIZE 65536
76 
80 static const char *sbin_sysctl;
81 
85 static const char *sbin_iptables;
86 
87 
88 #if ! defined(_LINUX_IN6_H) && defined(__linux__)
89 
92 struct in6_ifreq
93 {
94  struct in6_addr ifr6_addr;
95  uint32_t ifr6_prefixlen; /* __u32 in the original */
96  int ifr6_ifindex;
97 };
98 #endif
99 
100 
108 static void
109 open_dev_null (int target_fd,
110  int flags)
111 {
112  int fd;
113 
114  fd = open ("/dev/null", flags);
115  if (-1 == fd)
116  abort ();
117  if (fd == target_fd)
118  return;
119  if (-1 == dup2 (fd, target_fd))
120  {
121  (void) close (fd);
122  abort ();
123  }
124  (void) close (fd);
125 }
126 
127 
135 static int
136 fork_and_exec (const char *file,
137  char *const cmd[])
138 {
139  int status;
140  pid_t pid;
141  pid_t ret;
142 
143  pid = fork ();
144  if (-1 == pid)
145  {
146  fprintf (stderr,
147  "fork failed: %s\n",
148  strerror (errno));
149  return 1;
150  }
151  if (0 == pid)
152  {
153  /* we are the child process */
154  /* close stdin/stdout to not cause interference
155  with the helper's main protocol! */
156  (void) close (0);
157  open_dev_null (0, O_RDONLY);
158  (void) close (1);
159  open_dev_null (1, O_WRONLY);
160  (void) execv (file, cmd);
161  /* can only get here on error */
162  fprintf (stderr,
163  "exec `%s' failed: %s\n",
164  file,
165  strerror (errno));
166  _exit (1);
167  }
168  /* keep running waitpid as long as the only error we get is 'EINTR' */
169  while ((-1 == (ret = waitpid (pid, &status, 0))) &&
170  (errno == EINTR))
171  ;
172  if (-1 == ret)
173  {
174  fprintf (stderr,
175  "waitpid failed: %s\n",
176  strerror (errno));
177  return 1;
178  }
179  if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status))))
180  return 1;
181  /* child process completed and returned success, we're happy */
182  return 0;
183 }
184 
185 
193 #ifdef IFF_TUN /* LINUX */
194 static int
195 init_tun (char *dev)
196 {
197  struct ifreq ifr;
198  int fd;
199 
200  if (NULL == dev)
201  {
202  errno = EINVAL;
203  return -1;
204  }
205 
206  if (-1 == (fd = open ("/dev/net/tun", O_RDWR)))
207  {
208  fprintf (stderr, "Error opening `%s': %s\n", "/dev/net/tun",
209  strerror (errno));
210  return -1;
211  }
212 
213  if (fd >= FD_SETSIZE)
214  {
215  fprintf (stderr, "File descriptor to large: %d", fd);
216  (void) close (fd);
217  return -1;
218  }
219 
220  memset (&ifr, 0, sizeof(ifr));
221  ifr.ifr_flags = IFF_TUN;
222 
223  if ('\0' != *dev)
224  strncpy (ifr.ifr_name, dev, IFNAMSIZ);
225 
226  if (-1 == ioctl (fd, TUNSETIFF, (void *) &ifr))
227  {
228  fprintf (stderr,
229  "Error with ioctl on `%s': %s\n", "/dev/net/tun",
230  strerror (errno));
231  (void) close (fd);
232  return -1;
233  }
234  strcpy (dev, ifr.ifr_name);
235  return fd;
236 }
237 
238 
239 #else /* BSD et al, including DARWIN */
240 
241 #ifdef SIOCIFCREATE
242 static int
243 init_tun (char *dev)
244 {
245  int fd;
246  int s;
247  struct ifreq ifr;
248 
249  fd = open (dev, O_RDWR);
250  if (fd == -1)
251  {
252  s = socket (AF_INET, SOCK_DGRAM, 0);
253  if (s < 0)
254  return -1;
255  memset (&ifr, 0, sizeof(ifr));
256  strncpy (ifr.ifr_name, dev + 5, sizeof(ifr.ifr_name) - 1);
257  if (! ioctl (s, SIOCIFCREATE, &ifr))
258  fd = open (dev, O_RDWR);
259  close (s);
260  }
261  return fd;
262 }
263 
264 
265 #else
266 #define init_tun(dev) open (dev, O_RDWR)
267 #endif
268 #endif /* !IFF_TUN (BSD) */
269 
277 static void
278 set_address6 (const char *dev, const char *address, unsigned long prefix_len)
279 {
280  struct ifreq ifr;
281  struct sockaddr_in6 sa6;
282  int fd;
283  struct in6_ifreq ifr6;
284 
285  /*
286  * parse the new address
287  */
288  memset (&sa6, 0, sizeof(struct sockaddr_in6));
289  sa6.sin6_family = AF_INET6;
290  if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr))
291  {
292  fprintf (stderr, "Failed to parse address `%s': %s\n", address,
293  strerror (errno));
294  exit (1);
295  }
296 
297  if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0)))
298  {
299  fprintf (stderr, "Error creating socket: %s\n", strerror (errno));
300  exit (1);
301  }
302 
303  memset (&ifr, 0, sizeof(struct ifreq));
304  /*
305  * Get the index of the if
306  */
307  strncpy (ifr.ifr_name, dev, IFNAMSIZ);
308  if (-1 == ioctl (fd, SIOGIFINDEX, &ifr))
309  {
310  fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno));
311  (void) close (fd);
312  exit (1);
313  }
314 
315  memset (&ifr6, 0, sizeof(struct in6_ifreq));
316  ifr6.ifr6_addr = sa6.sin6_addr;
317  ifr6.ifr6_ifindex = ifr.ifr_ifindex;
318  ifr6.ifr6_prefixlen = prefix_len;
319 
320  /*
321  * Set the address
322  */
323  if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6))
324  {
325  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
326  strerror (errno));
327  (void) close (fd);
328  exit (1);
329  }
330 
331  /*
332  * Get the flags
333  */
334  if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
335  {
336  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
337  strerror (errno));
338  (void) close (fd);
339  exit (1);
340  }
341 
342  /*
343  * Add the UP and RUNNING flags
344  */
345  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
346  if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
347  {
348  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
349  strerror (errno));
350  (void) close (fd);
351  exit (1);
352  }
353 
354  if (0 != close (fd))
355  {
356  fprintf (stderr, "close failed: %s\n", strerror (errno));
357  exit (1);
358  }
359 }
360 
361 
369 static void
370 set_address4 (const char *dev, const char *address, const char *mask)
371 {
372  int fd;
373  struct sockaddr_in *addr;
374  struct ifreq ifr;
375 
376  memset (&ifr, 0, sizeof(struct ifreq));
377  addr = (struct sockaddr_in *) &(ifr.ifr_addr);
378  addr->sin_family = AF_INET;
379 
380  /*
381  * Parse the address
382  */
383  if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr))
384  {
385  fprintf (stderr, "Failed to parse address `%s': %s\n", address,
386  strerror (errno));
387  exit (1);
388  }
389 
390  if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0)))
391  {
392  fprintf (stderr, "Error creating socket: %s\n", strerror (errno));
393  exit (1);
394  }
395 
396  strncpy (ifr.ifr_name, dev, IFNAMSIZ);
397 
398  /*
399  * Set the address
400  */
401  if (-1 == ioctl (fd, SIOCSIFADDR, &ifr))
402  {
403  fprintf (stderr, "ioctl failed at %d: %s\n", __LINE__, strerror (errno));
404  (void) close (fd);
405  exit (1);
406  }
407 
408  /*
409  * Parse the netmask
410  */
411  addr = (struct sockaddr_in *) &(ifr.ifr_netmask);
412  if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr))
413  {
414  fprintf (stderr, "Failed to parse address `%s': %s\n", mask,
415  strerror (errno));
416  (void) close (fd);
417  exit (1);
418  }
419 
420  /*
421  * Set the netmask
422  */
423  if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr))
424  {
425  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
426  strerror (errno));
427  (void) close (fd);
428  exit (1);
429  }
430 
431  /*
432  * Get the flags
433  */
434  if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
435  {
436  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
437  strerror (errno));
438  (void) close (fd);
439  exit (1);
440  }
441 
442  /*
443  * Add the UP and RUNNING flags
444  */
445  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
446  if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
447  {
448  fprintf (stderr, "ioctl failed at line %d: %s\n", __LINE__,
449  strerror (errno));
450  (void) close (fd);
451  exit (1);
452  }
453 
454  if (0 != close (fd))
455  {
456  fprintf (stderr, "close failed: %s\n", strerror (errno));
457  (void) close (fd);
458  exit (1);
459  }
460 }
461 
462 
468 static void
469 run (int fd_tun)
470 {
471  /*
472  * The buffer filled by reading from fd_tun
473  */
474  unsigned char buftun[MAX_SIZE];
475  ssize_t buftun_size = 0;
476  unsigned char *buftun_read = NULL;
477 
478  /*
479  * The buffer filled by reading from stdin
480  */
481  unsigned char bufin[MAX_SIZE];
482  ssize_t bufin_size = 0;
483  size_t bufin_rpos = 0;
484  unsigned char *bufin_read = NULL;
485 
486  fd_set fds_w;
487  fd_set fds_r;
488 
489  /* read refers to reading from fd_tun, writing to stdout */
490  int read_open = 1;
491 
492  /* write refers to reading from stdin, writing to fd_tun */
493  int write_open = 1;
494 
495  while ((1 == read_open) && (1 == write_open))
496  {
497  FD_ZERO (&fds_w);
498  FD_ZERO (&fds_r);
499 
500  /*
501  * We are supposed to read and the buffer is empty
502  * -> select on read from tun
503  */
504  if (read_open && (0 == buftun_size))
505  FD_SET (fd_tun, &fds_r);
506 
507  /*
508  * We are supposed to read and the buffer is not empty
509  * -> select on write to stdout
510  */
511  if (read_open && (0 != buftun_size))
512  FD_SET (1, &fds_w);
513 
514  /*
515  * We are supposed to write and the buffer is empty
516  * -> select on read from stdin
517  */
518  if (write_open && (NULL == bufin_read))
519  FD_SET (0, &fds_r);
520 
521  /*
522  * We are supposed to write and the buffer is not empty
523  * -> select on write to tun
524  */
525  if (write_open && (NULL != bufin_read))
526  FD_SET (fd_tun, &fds_w);
527 
528  int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
529 
530  if (-1 == r)
531  {
532  if (EINTR == errno)
533  continue;
534  fprintf (stderr, "select failed: %s\n", strerror (errno));
535  exit (1);
536  }
537 
538  if (r > 0)
539  {
540  if (FD_ISSET (fd_tun, &fds_r))
541  {
542  buftun_size =
543  read (fd_tun, buftun + sizeof(struct GNUNET_MessageHeader),
544  MAX_SIZE - sizeof(struct GNUNET_MessageHeader));
545  if (-1 == buftun_size)
546  {
547  fprintf (stderr,
548  "read-error: %s\n",
549  strerror (errno));
550  shutdown (fd_tun, SHUT_RD);
551  shutdown (1, SHUT_WR);
552  read_open = 0;
553  buftun_size = 0;
554  }
555  else if (0 == buftun_size)
556  {
557 #if DEBUG
558  fprintf (stderr, "EOF on tun\n");
559 #endif
560  shutdown (fd_tun, SHUT_RD);
561  shutdown (1, SHUT_WR);
562  read_open = 0;
563  buftun_size = 0;
564  }
565  else
566  {
567  buftun_read = buftun;
568  struct GNUNET_MessageHeader *hdr =
569  (struct GNUNET_MessageHeader *) buftun;
570  buftun_size += sizeof(struct GNUNET_MessageHeader);
571  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
572  hdr->size = htons (buftun_size);
573  }
574  }
575  else if (FD_ISSET (1, &fds_w))
576  {
577  ssize_t written = write (1, buftun_read, buftun_size);
578 
579  if (-1 == written)
580  {
581 #if ! DEBUG
582  if (errno != EPIPE)
583 #endif
584  fprintf (stderr,
585  "write-error to stdout: %s\n",
586  strerror (errno));
587  shutdown (fd_tun, SHUT_RD);
588  shutdown (1, SHUT_WR);
589  read_open = 0;
590  buftun_size = 0;
591  }
592  else if (0 == written)
593  {
594  fprintf (stderr, "write returned 0!?\n");
595  exit (1);
596  }
597  else
598  {
599  buftun_size -= written;
600  buftun_read += written;
601  }
602  }
603 
604  if (FD_ISSET (0, &fds_r))
605  {
606  bufin_size = read (0, bufin + bufin_rpos, MAX_SIZE - bufin_rpos);
607  if (-1 == bufin_size)
608  {
609  fprintf (stderr, "read-error: %s\n", strerror (errno));
610  shutdown (0, SHUT_RD);
611  shutdown (fd_tun, SHUT_WR);
612  write_open = 0;
613  bufin_size = 0;
614  }
615  else if (0 == bufin_size)
616  {
617 #if DEBUG
618  fprintf (stderr, "EOF on stdin\n");
619 #endif
620  shutdown (0, SHUT_RD);
621  shutdown (fd_tun, SHUT_WR);
622  write_open = 0;
623  bufin_size = 0;
624  }
625  else
626  {
627  struct GNUNET_MessageHeader *hdr;
628 
629 PROCESS_BUFFER:
630  bufin_rpos += bufin_size;
631  if (bufin_rpos < sizeof(struct GNUNET_MessageHeader))
632  continue;
633  hdr = (struct GNUNET_MessageHeader *) bufin;
634  if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER)
635  {
636  fprintf (stderr, "protocol violation!\n");
637  exit (1);
638  }
639  if (ntohs (hdr->size) > bufin_rpos)
640  continue;
641  bufin_read = bufin + sizeof(struct GNUNET_MessageHeader);
642  bufin_size = ntohs (hdr->size) - sizeof(struct GNUNET_MessageHeader);
643  bufin_rpos -= bufin_size + sizeof(struct GNUNET_MessageHeader);
644  }
645  }
646  else if (FD_ISSET (fd_tun, &fds_w))
647  {
648  ssize_t written = write (fd_tun, bufin_read, bufin_size);
649 
650  if (-1 == written)
651  {
652  fprintf (stderr, "write-error to tun: %s\n", strerror (errno));
653  shutdown (0, SHUT_RD);
654  shutdown (fd_tun, SHUT_WR);
655  write_open = 0;
656  bufin_size = 0;
657  }
658  else if (0 == written)
659  {
660  fprintf (stderr, "write returned 0!?\n");
661  exit (1);
662  }
663  else
664  {
665  bufin_size -= written;
666  bufin_read += written;
667  if (0 == bufin_size)
668  {
669  memmove (bufin, bufin_read, bufin_rpos);
670  bufin_read = NULL; /* start reading again */
671  bufin_size = 0;
672  goto PROCESS_BUFFER;
673  }
674  }
675  }
676  }
677  }
678 }
679 
680 
694 int
695 main (int argc, char **argv)
696 {
697  char dev[IFNAMSIZ];
698  int fd_tun;
699  int global_ret;
700 
701  if (7 != argc)
702  {
703  fprintf (stderr, "Fatal: must supply 6 arguments!\n");
704  return 1;
705  }
706  if ((0 == strcmp (argv[3], "-")) &&
707  (0 == strcmp (argv[5], "-")))
708  {
709  fprintf (stderr, "Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
710  return 1;
711  }
712  if (0 != strcmp (argv[2], "-"))
713  {
714 #ifdef IPTABLES
715  if (0 == access (IPTABLES, X_OK))
716  sbin_iptables = IPTABLES;
717  else
718 #endif
719  if (0 == access ("/sbin/iptables", X_OK))
720  sbin_iptables = "/sbin/iptables";
721  else if (0 == access ("/usr/sbin/iptables", X_OK))
722  sbin_iptables = "/usr/sbin/iptables";
723  else
724  {
725  fprintf (stderr,
726  "Fatal: executable iptables not found in approved directories: %s\n",
727  strerror (errno));
728  return 1;
729  }
730 #ifdef SYSCTL
731  if (0 == access (SYSCTL, X_OK))
732  sbin_sysctl = SYSCTL;
733  else
734 #endif
735  if (0 == access ("/sbin/sysctl", X_OK))
736  sbin_sysctl = "/sbin/sysctl";
737  else if (0 == access ("/usr/sbin/sysctl", X_OK))
738  sbin_sysctl = "/usr/sbin/sysctl";
739  else
740  {
741  fprintf (stderr,
742  "Fatal: executable sysctl not found in approved directories: %s\n",
743  strerror (errno));
744  return 1;
745  }
746  }
747 
748  strncpy (dev, argv[1], IFNAMSIZ);
749  dev[IFNAMSIZ - 1] = '\0';
750 
751  if (-1 == (fd_tun = init_tun (dev)))
752  {
753  fprintf (stderr,
754  "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
755  dev,
756  argv[3],
757  argv[4],
758  argv[5],
759  argv[6]);
760  return 1;
761  }
762 
763  if (0 != strcmp (argv[3], "-"))
764  {
765  {
766  const char *address = argv[3];
767  long prefix_len = atol (argv[4]);
768 
769  if ((prefix_len < 1) || (prefix_len > 127))
770  {
771  fprintf (stderr, "Fatal: prefix_len out of range\n");
772  return 1;
773  }
774  set_address6 (dev, address, prefix_len);
775  }
776  if (0 != strcmp (argv[2], "-"))
777  {
778  char *const sysctl_args[] = {
779  "sysctl", "-w", "net.ipv6.conf.all.forwarding=1", NULL
780  };
781  if (0 != fork_and_exec (sbin_sysctl,
782  sysctl_args))
783  {
784  fprintf (stderr,
785  "Failed to enable IPv6 forwarding. Will continue anyway.\n");
786  }
787  }
788  }
789 
790  if (0 != strcmp (argv[5], "-"))
791  {
792  {
793  const char *address = argv[5];
794  const char *mask = argv[6];
795 
796  set_address4 (dev, address, mask);
797  }
798  if (0 != strcmp (argv[2], "-"))
799  {
800  {
801  char *const sysctl_args[] = {
802  "sysctl", "-w", "net.ipv4.ip_forward=1", NULL
803  };
804  if (0 != fork_and_exec (sbin_sysctl,
805  sysctl_args))
806  {
807  fprintf (stderr,
808  "Failed to enable IPv4 forwarding. Will continue anyway.\n");
809  }
810  }
811  {
812  char *const iptables_args[] = {
813  "iptables", "-t", "nat", "-A", "POSTROUTING", "-o", argv[2], "-j",
814  "MASQUERADE", NULL
815  };
816  if (0 != fork_and_exec (sbin_iptables,
817  iptables_args))
818  {
819  fprintf (stderr,
820  "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n");
821  }
822  }
823  }
824  }
825 
826  uid_t uid = getuid ();
827 #ifdef HAVE_SETRESUID
828  if (0 != setresuid (uid, uid, uid))
829  {
830  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
831  global_ret = 2;
832  goto cleanup;
833  }
834 #else
835  if (0 != (setuid (uid) | seteuid (uid)))
836  {
837  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
838  global_ret = 2;
839  goto cleanup;
840  }
841 #endif
842 
843  if (SIG_ERR == signal (SIGPIPE, SIG_IGN))
844  {
845  fprintf (stderr, "Failed to protect against SIGPIPE: %s\n",
846  strerror (errno));
847  /* no exit, we might as well die with SIGPIPE should it ever happen */
848  }
849  run (fd_tun);
850  global_ret = 0;
851 cleanup:
852  (void) close (fd_tun);
853  return global_ret;
854 }
855 
856 
857 /* end of gnunet-helper-exit.c */
uint32_t ifr6_prefixlen
static const char * sbin_iptables
Path to &#39;iptables&#39; binary.
static void run(int fd_tun)
Start forwarding to and from the tunnel.
struct in6_addr ifr6_addr
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
cryptographic primitives for GNUnet
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define MAX_SIZE
Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
static void open_dev_null(int target_fd, int flags)
Open &#39;/dev/null&#39; and make the result the given file descriptor.
uint16_t status
See PRISM_STATUS_*-constants.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static void set_address6(const char *dev, const char *address, unsigned long prefix_len)
Sets the IPv6-Address given in address on the interface dev.
static void set_address4(const char *dev, const char *address, const char *mask)
Sets the IPv4-Address given in address on the interface dev.
int main(int argc, char **argv)
Open VPN tunnel interface.
This is in linux/include/net/ipv6.h, but not always exported...
static const char * sbin_sysctl
Path to &#39;sysctl&#39; binary.
Header for all communications.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
static int fork_and_exec(const char *file, char *const cmd[])
Run the given command and wait for it to complete.
unsigned int ifr6_ifindex
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static char * address
GNS address for this phone.
static int global_ret
Return value from main.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
#define init_tun(dev)
Creates a tun-interface called dev;.