1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <linux/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "gnunet-vpn-helper-p.h"
#include "tun.h"
#ifndef _LINUX_IN6_H
// This is in linux/include/net/ipv6.h.
struct in6_ifreq {
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
unsigned int ifr6_ifindex;
};
#endif
static void set_address(char* dev, char* address, unsigned long prefix_len) { /* {{{ */
int fd = socket(AF_INET6, SOCK_DGRAM, 0);
struct ifreq ifr;
struct in6_ifreq ifr6;
struct sockaddr_in6 sa6;
memset(&sa6, 0, sizeof(struct sockaddr_in6));
sa6.sin6_family = AF_INET6;
/* FIXME */ inet_pton(AF_INET6, address, sa6.sin6_addr.s6_addr);
memcpy((char *) &ifr6.ifr6_addr, (char *) &sa6.sin6_addr, sizeof(struct in6_addr));
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
perror("SIOGIFINDEX");
}
ifr6.ifr6_ifindex = ifr.ifr_ifindex;
ifr6.ifr6_prefixlen = prefix_len;
if (ioctl(fd, SIOCSIFADDR, &ifr6) < 0) {
perror("SIOCSIFADDR");
}
/* FIXME */ ioctl(fd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
/* FIXME */ ioctl(fd, SIOCSIFFLAGS, &ifr);
} /* }}} */
int main(int argc, char** argv) {
char dev[IFNAMSIZ];
memset(dev, 0, IFNAMSIZ);
int fd_tun = init_tun(dev);
fprintf(stderr, "Initialized the interface %s as %d.\n", dev, fd_tun);
// TODO: get this out of argv
char address[] = "1234::1";
unsigned long prefix_len = 8;
set_address(dev, address, prefix_len);
uid_t uid = getuid ();
if (setresuid (uid, uid, uid) != 0 )
fprintf (stderr, "Failed to setresuid: %m\n");
// Wait
read(0, dev, 10);
return 0;
}
|