8 #include <sys/socket.h>
18 #include "gnunet-vpn-helper-p.h"
22 // This is in linux/include/net/ipv6.h.
25 struct in6_addr ifr6_addr;
27 unsigned int ifr6_ifindex;
35 fprintf(stderr, "Got SIGTERM...\n");
40 static void set_address(char* dev, char* address, unsigned long prefix_len) { /* {{{ */
41 int fd = socket(AF_INET6, SOCK_DGRAM, 0);
44 struct in6_ifreq ifr6;
46 struct sockaddr_in6 sa6;
47 memset(&sa6, 0, sizeof(struct sockaddr_in6));
49 sa6.sin6_family = AF_INET6;
51 /* FIXME */ inet_pton(AF_INET6, address, sa6.sin6_addr.s6_addr);
53 memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr));
55 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
57 if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
58 perror("SIOGIFINDEX");
61 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
62 ifr6.ifr6_prefixlen = prefix_len;
64 if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
65 perror("SIOCSIFADDR");
68 /* FIXME */ ioctl(fd, SIOCGIFFLAGS, &ifr);
69 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
70 /* FIXME */ ioctl(fd, SIOCSIFFLAGS, &ifr);
73 void setnonblocking(int fd) {
76 opts = fcntl(fd,F_GETFL);
78 perror("fcntl(F_GETFL)");
80 opts = (opts | O_NONBLOCK);
81 if (fcntl(fd,F_SETFL,opts) < 0) {
82 perror("fcntl(F_SETFL)");
87 static int copy (int in, int out) {
88 unsigned char buf[65600]; // 64k + 64;
89 int r = read(in, buf, 65600);
93 int t = write(out, buf + w, r - w);
100 int main(int argc, char** argv) {
102 memset(dev, 0, IFNAMSIZ);
104 signal(SIGTERM, &term);
106 int fd_tun = init_tun(dev);
107 fprintf(stderr, "Initialized the interface %s as %d.\n", dev, fd_tun);
109 // TODO: get this out of argv
110 char address[] = "1234::1";
111 unsigned long prefix_len = 8;
113 set_address(dev, address, prefix_len);
115 uid_t uid = getuid ();
116 if (setresuid (uid, uid, uid) != 0 )
117 fprintf (stderr, "Failed to setresuid: %m\n");
121 setnonblocking(fd_tun);
128 while(r != 0 && w != 0 && running == 1) {
133 FD_SET(fd_tun, &fds_r);
139 FD_SET(fd_tun, &fds_w);
142 int r = select(fd_tun+1, &fds_r, &fds_w, (fd_set*)0, 0);
145 if (FD_ISSET(0, &fds_r) && FD_ISSET(fd_tun, &fds_w)) {
146 if (copy(0, fd_tun) < 0) {
147 fprintf(stderr, "Closing Write\n");
148 shutdown(fd_tun, SHUT_WR);
151 } else if (FD_ISSET(1, &fds_w) && FD_ISSET(fd_tun, &fds_r)) {
152 if (copy(fd_tun, 1) < 0) {
153 fprintf(stderr, "Closing Read\n");
154 shutdown(fd_tun, SHUT_RD);
160 fprintf(stderr, "Quitting!\n");