How to open tap device on android using native code C?
Asked Answered
A

3

6

I am trying build a VPN client mobile for Android based applications that connect to virtual infrastructure over VPN tunnel. I have a similar application for Linux/Windows and I know how to open a tun/tap device (open /dev/net/tun). How do we do the same for Android using C ?

Also what does the class VpnService in the android.net API do exactly ?

Angelicangelica answered 14/7, 2014 at 20:29 Comment(0)
F
7

The VpnService class does exactly what you need. It provides an access to the tun device. You cannot directly open /dev/net/tun without having root rights. See the ToyVPN example project or an open source VPN project like OpenVPN for Android.

Fivestar answered 15/7, 2014 at 12:13 Comment(6)
Yes I did check those apps. I also checked an app "OpenVpn Client". In the description of that and apps similar to it they have mentioned "There is not needed to have the root access, because the VPN tun device is handled with the VpnService API introduced with Android 4.0 (ICS). Also provides tap device support." So does VpnService class provide tap support as well w/o having to root the device?Angelicangelica
no only tun. For tap see faq of OpenVPN for Android. Basically you can emulate tap with a tun device but you have write a small wrapper/pay someone to write itFivestar
So I was able to establish a VPN connection, got the parameter (IP address, DNS server address etc). Further when I try to create an interface using those parameter by the builder.establish method, I get the following error. java.lang.IllegalStateException: command '88 interface fwmark rule add tun0' failed with '400 88 Failed to add fwmark rule (No such device)' I do not have root access and what I had read error was we do not need root access to have access to tun device. So why am I not able to get the device up? What am I missing?Angelicangelica
In short broken device. The 4.4er emulator is broken too.Fivestar
So what is the workaround or solution to the same? Really appreciate your insights..Angelicangelica
I have no solution or workaround gut for these devices, sorryFivestar
P
10

If you still wants to open a tunnel on android - native C, I suggest to take a look how android itself open it (from file: services/jni/com_android_server_connectivity_Vpn.cpp)

static int create_interface(int mtu)
{
    int tun = open("/dev/tun", O_RDWR | O_NONBLOCK);
    ifreq ifr4;
    memset(&ifr4, 0, sizeof(ifr4));
    // Allocate interface.
    ifr4.ifr_flags = IFF_TUN | IFF_NO_PI;
    if (ioctl(tun, TUNSETIFF, &ifr4)) {
        ALOGE("Cannot allocate TUN: %s", strerror(errno));
        goto error;
    }
    // Activate interface.
    ifr4.ifr_flags = IFF_UP;
    if (ioctl(inet4, SIOCSIFFLAGS, &ifr4)) {
        ALOGE("Cannot activate %s: %s", ifr4.ifr_name, strerror(errno));
        goto error;
    }
    // Set MTU if it is specified.
    ifr4.ifr_mtu = mtu;
    if (mtu > 0 && ioctl(inet4, SIOCSIFMTU, &ifr4)) {
        ALOGE("Cannot set MTU on %s: %s", ifr4.ifr_name, strerror(errno));
        goto error;
    }
    return tun;
error:
    close(tun);
    return SYSTEM_ERROR;
}
Pledget answered 25/1, 2015 at 9:26 Comment(0)
F
7

The VpnService class does exactly what you need. It provides an access to the tun device. You cannot directly open /dev/net/tun without having root rights. See the ToyVPN example project or an open source VPN project like OpenVPN for Android.

Fivestar answered 15/7, 2014 at 12:13 Comment(6)
Yes I did check those apps. I also checked an app "OpenVpn Client". In the description of that and apps similar to it they have mentioned "There is not needed to have the root access, because the VPN tun device is handled with the VpnService API introduced with Android 4.0 (ICS). Also provides tap device support." So does VpnService class provide tap support as well w/o having to root the device?Angelicangelica
no only tun. For tap see faq of OpenVPN for Android. Basically you can emulate tap with a tun device but you have write a small wrapper/pay someone to write itFivestar
So I was able to establish a VPN connection, got the parameter (IP address, DNS server address etc). Further when I try to create an interface using those parameter by the builder.establish method, I get the following error. java.lang.IllegalStateException: command '88 interface fwmark rule add tun0' failed with '400 88 Failed to add fwmark rule (No such device)' I do not have root access and what I had read error was we do not need root access to have access to tun device. So why am I not able to get the device up? What am I missing?Angelicangelica
In short broken device. The 4.4er emulator is broken too.Fivestar
So what is the workaround or solution to the same? Really appreciate your insights..Angelicangelica
I have no solution or workaround gut for these devices, sorryFivestar
M
0

You need to be root to open tuntap on Android.

this->_handle = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
if (this->_handle < 0) {
  this->_handle = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC); 
}

For details: https://android.googlesource.com/platform/frameworks/base.git/+/android-4.3_r2.1/services/jni/com_android_server_connectivity_Vpn.cpp

Supplement:

  1. /dev/tun and /dev/net/tun both require an attempt to open the device. There are too many distributions of Android, each with individual changes, and tuntap devices are also slightly different.

  2. Native-code may not be a good idea to open a tuntap!

Monofilament answered 24/1, 2022 at 3:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.