summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/main.c b/main.c
index 54d12d1..9e796fd 100644
--- a/main.c
+++ b/main.c
@@ -46,6 +46,7 @@ void print_help() {
printf("-6 [IPv6 address]\n");
printf("-n [NetId]\n");
printf("-m [socket mark]\n");
+ printf("-t [tun file descriptor number]\n");
}
/* function: main
@@ -55,12 +56,12 @@ int main(int argc, char **argv) {
struct tun_data tunnel;
int opt;
char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
- char *v4_addr = NULL, *v6_addr = NULL;
+ char *v4_addr = NULL, *v6_addr = NULL, *tunfd_str = NULL;
unsigned net_id = NETID_UNSET;
uint32_t mark = MARK_UNSET;
unsigned len;
- while ((opt = getopt(argc, argv, "i:p:4:6:n:m:h")) != -1) {
+ while ((opt = getopt(argc, argv, "i:p:4:6:n:m:t:h")) != -1) {
switch (opt) {
case 'i':
uplink_interface = optarg;
@@ -80,6 +81,9 @@ int main(int argc, char **argv) {
case 'm':
mark_str = optarg;
break;
+ case 't':
+ tunfd_str = optarg;
+ break;
case 'h':
print_help();
exit(0);
@@ -104,6 +108,15 @@ int main(int argc, char **argv) {
exit(1);
}
+ if (tunfd_str != NULL && !parse_int(tunfd_str, &tunnel.fd4)) {
+ logmsg(ANDROID_LOG_FATAL, "invalid tunfd %s", tunfd_str);
+ exit(1);
+ }
+ if (!tunnel.fd4) {
+ logmsg(ANDROID_LOG_FATAL, "no tunfd specified on commandline.");
+ exit(1);
+ }
+
len = snprintf(tunnel.device4, sizeof(tunnel.device4), "%s%s", DEVICEPREFIX, uplink_interface);
if (len >= sizeof(tunnel.device4)) {
logmsg(ANDROID_LOG_FATAL, "interface name too long '%s'", tunnel.device4);
@@ -124,13 +137,6 @@ int main(int argc, char **argv) {
// keeps only admin capability
set_capability(1 << CAP_NET_ADMIN);
- // we can create tun devices as non-root because we're in the VPN group.
- tunnel.fd4 = tun_open();
- if (tunnel.fd4 < 0) {
- logmsg(ANDROID_LOG_FATAL, "tun_open4 failed: %s", strerror(errno));
- exit(1);
- }
-
// When run from netd, the environment variable ANDROID_DNS_MODE is set to
// "local", but that only works for the netd process itself. Removing the
// following line causes XLAT failure in permissive mode.