18
18
#include "output.h"
20
static void tuntap_up(int fd, char *gate_addr)
20
static int do_tuntap_up(char *gate_addr, struct output *output,
24
char *ifconfig_argv[] = { "ifconfig", ifr->ifr_name, gate_addr, "netmask",
25
"255.255.255.255", "up", NULL };
26
char *insmod_argv[] = { "modprobe", "tun", NULL };
28
if(setreuid(0, 0) < 0){
29
output_errno(output, "setreuid to root failed : ");
33
/* XXX hardcoded dir name and perms */
35
mkdir("/dev/net", 0755);
37
/* #includes for MISC_MAJOR and TUN_MINOR bomb in userspace */
38
mk_node("/dev/net/tun", 10, 200);
40
do_exec(insmod_argv, 0, output);
42
if((tap_fd = open("/dev/net/tun", O_RDWR)) < 0){
43
output_errno(output, "Opening /dev/net/tun failed : ");
46
memset(ifr, 0, sizeof(*ifr));
47
ifr->ifr_flags = IFF_TAP | IFF_NO_PI;
48
ifr->ifr_name[0] = '\0';
49
if(ioctl(tap_fd, TUNSETIFF, (void *) ifr) < 0){
50
output_errno(output, "TUNSETIFF : ");
54
if((*gate_addr != '\0') && do_exec(ifconfig_argv, 1, output))
60
static void tuntap_up(int fd, int argc, char **argv)
24
char anc[CMSG_SPACE(sizeof(tap_fd))];
26
64
struct cmsghdr *cmsg;
27
char *ifconfig_argv[] = { "ifconfig", ifr.ifr_name, gate_addr, "netmask",
28
"255.255.255.255", "up", NULL };
29
char *insmod_argv[] = { "insmod", "tun", NULL };
30
65
struct output output = INIT_OUTPUT;
31
66
struct iovec iov[2];
68
char anc[CMSG_SPACE(sizeof(tap_fd))];
34
71
msg.msg_control = NULL;
35
72
msg.msg_controllen = 0;
37
74
iov[0].iov_base = NULL;
38
75
iov[0].iov_len = 0;
40
if(setreuid(0, 0) < 0){
41
output_errno(&output, "setreuid to root failed : ");
45
/* XXX hardcoded dir name and perms */
47
retval = mkdir("/dev/net", 0755);
49
/* #includes for MISC_MAJOR and TUN_MINOR bomb in userspace */
50
mk_node("/dev/net/tun", 10, 200);
52
do_exec(insmod_argv, 0, &output);
54
if((tap_fd = open("/dev/net/tun", O_RDWR)) < 0){
55
output_errno(&output, "Opening /dev/net/tun failed : ");
58
memset(&ifr, 0, sizeof(ifr));
59
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
60
ifr.ifr_name[0] = '\0';
61
if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){
62
output_errno(&output, "TUNSETIFF : ");
66
if((*gate_addr != '\0') && do_exec(ifconfig_argv, 1, &output)) goto out;
69
iov[0].iov_base = ifr.ifr_name;
70
iov[0].iov_len = IFNAMSIZ;
72
msg.msg_control = anc;
73
msg.msg_controllen = sizeof(anc);
75
cmsg = CMSG_FIRSTHDR(&msg);
76
cmsg->cmsg_level = SOL_SOCKET;
77
cmsg->cmsg_type = SCM_RIGHTS;
78
cmsg->cmsg_len = CMSG_LEN(sizeof(tap_fd));
80
msg.msg_controllen = cmsg->cmsg_len;
82
fd_ptr = (int *) CMSG_DATA(cmsg);
78
add_output(&output, "Too few arguments to tuntap_up\n", -1);
83
if((tap_fd = do_tuntap_up(gate_addr, &output, &ifr)) > 0){
84
iov[0].iov_base = ifr.ifr_name;
85
iov[0].iov_len = IFNAMSIZ;
87
msg.msg_control = anc;
88
msg.msg_controllen = sizeof(anc);
90
cmsg = CMSG_FIRSTHDR(&msg);
91
cmsg->cmsg_level = SOL_SOCKET;
92
cmsg->cmsg_type = SCM_RIGHTS;
93
cmsg->cmsg_len = CMSG_LEN(sizeof(tap_fd));
95
msg.msg_controllen = cmsg->cmsg_len;
97
fd_ptr = (int *) CMSG_DATA(cmsg);
86
102
iov[1].iov_base = output.buffer;
103
119
char *op = argv[0];
105
if(!strcmp(op, "up")) tuntap_up(atoi(argv[2]), argv[3]);
121
if(!strcmp(op, "up")) tuntap_up(atoi(argv[2]), argc - 3, argv + 3);
106
122
else if(!strcmp(op, "add") || !strcmp(op, "del"))
107
123
change_addr(argv[1], argv[2], argv[3], NULL, NULL);
116
132
char *op = argv[0];
117
133
struct output output = INIT_OUTPUT;
119
if(!strcmp(op, "up")) tuntap_up(1, argv[2]);
135
if(!strcmp(op, "up")) tuntap_up(1, argc - 2, argv + 2);
120
136
else if(!strcmp(op, "add") || !strcmp(op, "del"))
121
137
change_addr(op, argv[1], argv[2], NULL, &output);
129
145
void tuntap_v4(int argc, char **argv)
132
148
struct output output = INIT_OUTPUT;
134
if(!strcmp(op, "up")) tuntap_up(1, argv[1]);
135
else if(!strcmp(op, "add") || !strcmp(op, "del"))
136
change_addr(op, argv[1], argv[2], argv[3], &output);
151
add_output(&output, "uml_net : too few arguments to tuntap_v4\n", -1);
152
write_output(1, &output);
156
if(!strcmp(op, "up")) tuntap_up(1, argc - 1, argv + 1);
157
else if(!strcmp(op, "add") || !strcmp(op, "del")){
159
add_output(&output, "uml_net : too few arguments to tuntap "
160
"change_addr\n", -1);
161
else change_addr(op, argv[1], argv[2], argv[3], &output);
162
write_output(1, &output);
138
165
fprintf(stderr, "Bad tuntap op : '%s'\n", op);
141
write_output(1, &output);