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 int main(int argc, char** argv) {
88 unsigned char buf[65600]; // 64k + 64;
91 memset(dev, 0, IFNAMSIZ);
93 signal(SIGTERM, &term);
95 int fd_tun = init_tun(dev);
96 fprintf(stderr, "Initialized the interface %s as %d.\n", dev, fd_tun);
98 // TODO: get this out of argv
99 char address[] = "1234::1";
100 unsigned long prefix_len = 8;
102 set_address(dev, address, prefix_len);
104 uid_t uid = getuid ();
105 if (setresuid (uid, uid, uid) != 0 )
106 fprintf (stderr, "Failed to setresuid: %m\n");
110 setnonblocking(fd_tun);
118 while(rea != 0 && wri != 0 && running == 1) {
123 FD_SET(fd_tun, &fds_r);
129 FD_SET(fd_tun, &fds_w);
132 int r = select(fd_tun+1, &fds_r, &fds_w, (fd_set*)0, 0);
135 if (FD_ISSET(0, &fds_r) && FD_ISSET(fd_tun, &fds_w)) {
136 struct suid_packet *pkt = (struct suid_packet*) buf;
137 r = read(0, buf, sizeof(struct suid_packet_header));
139 fprintf(stderr, "read-error: %m\n");
140 shutdown(fd_tun, SHUT_WR);
141 shutdown(0, SHUT_RD);
146 while (r < ntohl(pkt->hdr.size)) {
147 int t = read(0, buf + r, ntohl(pkt->hdr.size) - r);
149 fprintf(stderr, "read-error: %m\n");
150 shutdown(fd_tun, SHUT_WR);
151 shutdown(0, SHUT_RD);
158 while (r < ntohl(pkt->hdr.size) - sizeof(struct suid_packet_header)) {
159 int t = write(fd_tun, pkt->data, ntohl(pkt->hdr.size) - sizeof(struct suid_packet_header) - r);
161 fprintf(stderr, "write-error 3: %m\n");
162 shutdown(fd_tun, SHUT_WR);
163 shutdown(0, SHUT_RD);
169 } else if (FD_ISSET(1, &fds_w) && FD_ISSET(fd_tun, &fds_r)) {
170 r = read(fd_tun, buf, 65600);
172 fprintf(stderr, "read-error: %m\n");
173 shutdown(fd_tun, SHUT_RD);
174 shutdown(1, SHUT_WR);
178 struct suid_packet_header hdr = { .size = htonl(r + sizeof(struct suid_packet_header))};
180 while(r < sizeof(struct suid_packet_header)) {
181 int t = write(1, &hdr, sizeof(struct suid_packet_header) - r);
183 fprintf(stderr, "write-error 2: %m\n");
184 shutdown(fd_tun, SHUT_RD);
185 shutdown(1, SHUT_WR);
191 while(r < ntohl(hdr.size)) {
192 int t = write(1, buf, ntohl(hdr.size) - r);
194 fprintf(stderr, "write-error 1: %m, written %d/%d\n", r, ntohl(hdr.size));
195 shutdown(fd_tun, SHUT_RD);
196 shutdown(1, SHUT_WR);
205 fprintf(stderr, "Quitting!\n");