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))
162 (void) execv (file, 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;
497 while ((1 == read_open) && (1 == write_open))
506 if (read_open && (0 == buftun_size))
507 FD_SET (fd_tun, &fds_r);
513 if (read_open && (0 != buftun_size))
520 if (write_open && (NULL == bufin_read))
527 if (write_open && (NULL != bufin_read))
528 FD_SET (fd_tun, &fds_w);
530 int r = select (fd_tun + 1, &fds_r, &fds_w, NULL, NULL);
536 fprintf (stderr,
"select failed: %s\n", strerror (errno));
542 if (FD_ISSET (fd_tun, &fds_r))
547 if (-1 == buftun_size)
552 shutdown (fd_tun, SHUT_RD);
553 shutdown (1, SHUT_WR);
557 else if (0 == buftun_size)
560 fprintf (stderr,
"EOF on tun\n");
562 shutdown (fd_tun, SHUT_RD);
563 shutdown (1, SHUT_WR);
569 buftun_read = buftun;
574 hdr->
size = htons (buftun_size);
577 else if (FD_ISSET (1, &fds_w))
579 ssize_t written = write (1, buftun_read, buftun_size);
587 "write-error to stdout: %s\n",
589 shutdown (fd_tun, SHUT_RD);
590 shutdown (1, SHUT_WR);
594 else if (0 == written)
596 fprintf (stderr,
"write returned 0!?\n");
601 buftun_size -= written;
602 buftun_read += written;
606 if (FD_ISSET (0, &fds_r))
608 bufin_size = read (0, bufin + bufin_rpos,
MAX_SIZE - bufin_rpos);
609 if (-1 == bufin_size)
611 fprintf (stderr,
"read-error: %s\n", strerror (errno));
612 shutdown (0, SHUT_RD);
613 shutdown (fd_tun, SHUT_WR);
617 else if (0 == bufin_size)
620 fprintf (stderr,
"EOF on stdin\n");
622 shutdown (0, SHUT_RD);
623 shutdown (fd_tun, SHUT_WR);
632 bufin_rpos += bufin_size;
638 fprintf (stderr,
"protocol violation!\n");
641 if (ntohs (hdr->
size) > bufin_rpos)
648 else if (FD_ISSET (fd_tun, &fds_w))
650 ssize_t written = write (fd_tun, bufin_read, bufin_size);
654 fprintf (stderr,
"write-error to tun: %s\n", strerror (errno));
655 shutdown (0, SHUT_RD);
656 shutdown (fd_tun, SHUT_WR);
660 else if (0 == written)
662 fprintf (stderr,
"write returned 0!?\n");
667 bufin_size -= written;
668 bufin_read += written;
671 memmove (bufin, bufin_read, bufin_rpos);
705 fprintf (stderr,
"Fatal: must supply 6 arguments!\n");
708 if ((0 == strcmp (argv[3],
"-")) &&
709 (0 == strcmp (argv[5],
"-")))
711 fprintf (stderr,
"Fatal: disabling both IPv4 and IPv6 makes no sense.\n");
714 if (0 != strcmp (argv[2],
"-"))
717 if (0 == access (IPTABLES, X_OK))
721 if (0 == access (
"/sbin/iptables", X_OK))
723 else if (0 == access (
"/usr/sbin/iptables", X_OK))
728 "Fatal: executable iptables not found in approved directories: %s\n",
733 if (0 == access (SYSCTL, X_OK))
737 if (0 == access (
"/sbin/sysctl", X_OK))
739 else if (0 == access (
"/usr/sbin/sysctl", X_OK))
744 "Fatal: executable sysctl not found in approved directories: %s\n",
750 strncpy (dev, argv[1], IFNAMSIZ);
751 dev[IFNAMSIZ - 1] =
'\0';
753 if (-1 == (fd_tun =
init_tun (dev)))
756 "Fatal: could not initialize tun-interface `%s' with IPv6 %s/%s and IPv4 %s/%s\n",
765 if (0 != strcmp (argv[3],
"-"))
769 long prefix_len = atol (argv[4]);
771 if ((prefix_len < 1) || (prefix_len > 127))
773 fprintf (stderr,
"Fatal: prefix_len out of range\n");
778 if (0 != strcmp (argv[2],
"-"))
780 char *
const sysctl_args[] = {
781 "sysctl",
"-w",
"net.ipv6.conf.all.forwarding=1", NULL
787 "Failed to enable IPv6 forwarding. Will continue anyway.\n");
792 if (0 != strcmp (argv[5],
"-"))
796 const char *mask = argv[6];
800 if (0 != strcmp (argv[2],
"-"))
803 char *
const sysctl_args[] = {
804 "sysctl",
"-w",
"net.ipv4.ip_forward=1", NULL
810 "Failed to enable IPv4 forwarding. Will continue anyway.\n");
814 char *
const iptables_args[] = {
815 "iptables",
"-t",
"nat",
"-A",
"POSTROUTING",
"-o", argv[2],
"-j",
822 "Failed to enable IPv4 masquerading (NAT). Will continue anyway.\n");
828 uid_t uid = getuid ();
830 if (0 != setresuid (uid, uid, uid))
832 fprintf (stderr,
"Failed to setresuid: %s\n", strerror (errno));
837 if (0 != (setuid (uid) | seteuid (uid)))
839 fprintf (stderr,
"Failed to setuid: %s\n", strerror (errno));
845 if (SIG_ERR == signal (SIGPIPE, SIG_IGN))
847 fprintf (stderr,
"Failed to protect against SIGPIPE: %s\n",
854 (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.
static int fork_and_exec(const char *file, char *const cmd[])
Run the given command and wait for it to complete.
int main(int argc, char **argv)
Open VPN tunnel interface.
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