50#if defined(BSD) || defined(SOLARIS)
51#define ifr_netmask ifr_ifru.ifru_addr
52#define SIOGIFINDEX SIOCGIFINDEX
70#define DEBUG GNUNET_NO
88#if ! defined(__ANDROID__)
89#if ! defined(_LINUX_IN6_H) && defined(__linux__)
116 fd = open (
"/dev/null", flags);
121 if (-1 == dup2 (fd, target_fd))
139 const char *
const cmd[])
162 (void) execv (file, (
char *
const *) cmd);
165 "exec `%s' failed: %s\n",
177 "waitpid failed: %s\n",
181 if (! (WIFEXITED (
status) && (0 == WEXITSTATUS (
status))))
208 if (-1 == (fd = open (
"/dev/net/tun", O_RDWR)))
210 fprintf (stderr,
"Error opening `%s': %s\n",
"/dev/net/tun",
215 if (fd >= FD_SETSIZE)
217 fprintf (stderr,
"File descriptor to large: %d", fd);
222 memset (&ifr, 0,
sizeof(ifr));
223 ifr.ifr_flags = IFF_TUN;
226 strncpy (ifr.ifr_name, dev, IFNAMSIZ);
228 if (-1 == ioctl (fd, TUNSETIFF, (
void *) &ifr))
231 "Error with ioctl on `%s': %s\n",
"/dev/net/tun",
236 strcpy (dev, ifr.ifr_name);
251 fd = open (dev, O_RDWR);
254 s = socket (AF_INET, SOCK_DGRAM, 0);
257 memset (&ifr, 0,
sizeof(ifr));
258 strncpy (ifr.ifr_name, dev + 5,
sizeof(ifr.ifr_name) - 1);
259 if (! ioctl (s, SIOCIFCREATE, &ifr))
260 fd = open (dev, O_RDWR);
268#define init_tun(dev) open (dev, O_RDWR)
283 struct sockaddr_in6 sa6;
290 memset (&sa6, 0,
sizeof(
struct sockaddr_in6));
291 sa6.sin6_family = AF_INET6;
292 if (1 != inet_pton (AF_INET6,
address, &sa6.sin6_addr))
294 fprintf (stderr,
"Failed to parse address `%s': %s\n",
address,
299 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0)))
301 fprintf (stderr,
"Error creating socket: %s\n", strerror (errno));
305 memset (&ifr, 0,
sizeof(
struct ifreq));
309 strncpy (ifr.ifr_name, dev, IFNAMSIZ);
310 if (-1 == ioctl (fd, SIOGIFINDEX, &ifr))
312 fprintf (stderr,
"ioctl failed at %d: %s\n", __LINE__, strerror (errno));
317 memset (&ifr6, 0,
sizeof(
struct in6_ifreq));
325 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr6))
327 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
336 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
338 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
347 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
348 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
350 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
358 fprintf (stderr,
"close failed: %s\n", strerror (errno));
375 struct sockaddr_in *addr;
378 memset (&ifr, 0,
sizeof(
struct ifreq));
379 addr = (
struct sockaddr_in *) &(ifr.ifr_addr);
380 addr->sin_family = AF_INET;
385 if (1 != inet_pton (AF_INET,
address, &addr->sin_addr.s_addr))
387 fprintf (stderr,
"Failed to parse address `%s': %s\n",
address,
392 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0)))
394 fprintf (stderr,
"Error creating socket: %s\n", strerror (errno));
398 strncpy (ifr.ifr_name, dev, IFNAMSIZ);
403 if (-1 == ioctl (fd, SIOCSIFADDR, &ifr))
405 fprintf (stderr,
"ioctl failed at %d: %s\n", __LINE__, strerror (errno));
413 addr = (
struct sockaddr_in *) &(ifr.ifr_netmask);
414 if (1 != inet_pton (AF_INET, mask, &addr->sin_addr.s_addr))
416 fprintf (stderr,
"Failed to parse address `%s': %s\n", mask,
425 if (-1 == ioctl (fd, SIOCSIFNETMASK, &ifr))
427 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
436 if (-1 == ioctl (fd, SIOCGIFFLAGS, &ifr))
438 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
447 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
448 if (-1 == ioctl (fd, SIOCSIFFLAGS, &ifr))
450 fprintf (stderr,
"ioctl failed at line %d: %s\n", __LINE__,
458 fprintf (stderr,
"close failed: %s\n", strerror (errno));
477 ssize_t buftun_size = 0;
478 unsigned char *buftun_read = NULL;
484 ssize_t bufin_size = 0;
485 size_t bufin_rpos = 0;
486 unsigned char *bufin_read = NULL;
498 while ((1 == read_open) && (1 == write_open))
507 if (read_open && (0 == buftun_size))
508 FD_SET (fd_tun, &fds_r);
514 if (read_open && (0 != buftun_size))
521 if (write_open && (NULL == bufin_read))
528 if (write_open && (NULL != bufin_read))
529 FD_SET (fd_tun, &fds_w);
531 r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
537 fprintf (stderr,
"select failed: %s\n", strerror (errno));
543 if (FD_ISSET (fd_tun, &fds_r))
548 if (-1 == buftun_size)
553 shutdown (fd_tun, SHUT_RD);
554 shutdown (1, SHUT_WR);
558 else if (0 == buftun_size)
561 fprintf (stderr,
"EOF on tun\n");
563 shutdown (fd_tun, SHUT_RD);
564 shutdown (1, SHUT_WR);
572 buftun_read = buftun;
575 hdr->
size = htons (buftun_size);
578 else if (FD_ISSET (1, &fds_w))
580 ssize_t written = write (1, buftun_read, buftun_size);
588 "write-error to stdout: %s\n",
590 shutdown (fd_tun, SHUT_RD);
591 shutdown (1, SHUT_WR);
595 else if (0 == written)
597 fprintf (stderr,
"write returned 0!?\n");
602 buftun_size -= written;
603 buftun_read += written;
607 if (FD_ISSET (0, &fds_r))
609 bufin_size = read (0, bufin + bufin_rpos,
MAX_SIZE - bufin_rpos);
610 if (-1 == bufin_size)
612 fprintf (stderr,
"read-error: %s\n", strerror (errno));
613 shutdown (0, SHUT_RD);
614 shutdown (fd_tun, SHUT_WR);
618 else if (0 == bufin_size)
621 fprintf (stderr,
"EOF on stdin\n");
623 shutdown (0, SHUT_RD);
624 shutdown (fd_tun, SHUT_WR);
633 bufin_rpos += bufin_size;
639 fprintf (stderr,
"protocol violation!\n");
642 if (ntohs (hdr->
size) > bufin_rpos)
649 else if (FD_ISSET (fd_tun, &fds_w))
651 ssize_t written = write (fd_tun, bufin_read, bufin_size);
655 fprintf (stderr,
"write-error to tun: %s\n", strerror (errno));
656 shutdown (0, SHUT_RD);
657 shutdown (fd_tun, SHUT_WR);
661 else if (0 == written)
663 fprintf (stderr,
"write returned 0!?\n");
668 bufin_size -= written;
669 bufin_read += written;
672 memmove (bufin, bufin_read, bufin_rpos);
706 fprintf (stderr,
"Fatal: must supply 6 arguments!\n");
709 if ((0 == strcmp (argv[3],
"-")) &&
710 (0 == strcmp (argv[5],
"-")))
712 fprintf (stderr,
"Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
715 if (0 != strcmp (argv[2],
"-"))
718 if (0 == access (IPTABLES, X_OK))
722 if (0 == access (
"/sbin/iptables", X_OK))
724 else if (0 == access (
"/usr/sbin/iptables", X_OK))
729 "Fatal: executable iptables not found in approved directories: %s\n",
734 if (0 == access (SYSCTL, X_OK))
738 if (0 == access (
"/sbin/sysctl", X_OK))
740 else if (0 == access (
"/usr/sbin/sysctl", X_OK))
745 "Fatal: executable sysctl not found in approved directories: %s\n",
751 strncpy (dev, argv[1], IFNAMSIZ);
752 dev[IFNAMSIZ - 1] =
'\0';
754 if (-1 == (fd_tun =
init_tun (dev)))
757 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
766 if (0 != strcmp (argv[3],
"-"))
770 long prefix_len = atol (argv[4]);
772 if ((prefix_len < 1) || (prefix_len > 127))
774 fprintf (stderr,
"Fatal: prefix_len out of range\n");
779 if (0 != strcmp (argv[2],
"-"))
781 const char *
const sysctl_args[] = {
782 "sysctl",
"-w",
"net.ipv6.conf.all.forwarding=1", NULL
788 "Failed to enable IPv6 forwarding. Will continue anyway.\n");
793 if (0 != strcmp (argv[5],
"-"))
797 const char *mask = argv[6];
801 if (0 != strcmp (argv[2],
"-"))
804 const char *
const sysctl_args[] = {
805 "sysctl",
"-w",
"net.ipv4.ip_forward=1", NULL
811 "Failed to enable IPv4 forwarding. Will continue anyway.\n")
816 const char *
const iptables_args[] = {
817 "iptables",
"-t",
"nat",
"-A",
"POSTROUTING",
"-o", argv[2],
"-j",
824 "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n");
831 uid_t uid = getuid ();
833 if (0 != setresuid (uid, uid, uid))
835 fprintf (stderr,
"Failed to setresuid: %s\n", strerror (errno));
840 if (0 != (setuid (uid) | seteuid (uid)))
842 fprintf (stderr,
"Failed to setuid: %s\n", strerror (errno));
849 if (SIG_ERR == signal (SIGPIPE, SIG_IGN))
851 fprintf (stderr,
"Failed to protect against SIGPIPE: %s\n",
858 (void) close (fd_tun);
static int ret
Final status code.
static char * address
GNS address for this phone.
static int global_ret
Global status value.
static void cleanup(void *cls)
Disconnect and shutdown.
#define MAX_SIZE
Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)
static const char * sbin_sysctl
Path to 'sysctl' binary.
static void run(int fd_tun)
Start forwarding to and from the tunnel.
int main(int argc, char **argv)
Open VPN tunnel interface.
static int fork_and_exec(const char *file, const char *const cmd[])
Run the given command and wait for it to complete.
static const char * sbin_iptables
Path to 'iptables' binary.
static void open_dev_null(int target_fd, int flags)
Open '/dev/null' and make the result the given file descriptor.
static void set_address4(const char *dev, const char *address, const char *mask)
Sets the IPv4-Address given in address on the interface dev.
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.
#define init_tun(dev)
Creates a tun-interface called dev;.
static int status
The program status; 0 for success.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Constants for network protocols.
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.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
This is in linux/include/net/ipv6.h, but not always exported...
struct in6_addr ifr6_addr
unsigned int ifr6_ifindex