6

我正在尝试为基于 Android 的应用程序构建一个 VPN 客户端移动设备,这些应用程序通过 VPN 隧道连接到虚拟基础设施。我有一个类似的 Linux/Windows 应用程序,我知道如何打开 tun/tap 设备(打开 /dev/net/tun)。我们如何使用 C 为 Android 做同样的事情?

另外,android.net API 中的 VpnService 类究竟做了什么?

4

3 回答 3

10

如果您仍然想在 android - native C 上打开隧道,我建议您看看 android 本身如何打开它(来自文件: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;
}
于 2015-01-25T09:26:48.650 回答
7

VpnService 类正是您所需要的。它提供对 tun 设备的访问。如果没有 root 权限,您无法直接打开 /dev/net/tun。请参阅 ToyVPN 示例项目或 OpenVPN for Android 等开源 VPN 项目。

于 2014-07-15T12:13:13.853 回答
0

您需要root在 Android 上打开 tuntap。

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); 
}

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

补充:

  1. /dev/tun两者/dev/net/tun都需要尝试打开设备。Android 的发行版太多了,每个发行版都有各自的变化,而且 tuntap 设备也略有不同。

  2. 本机代码可能不是打开 tuntap 的好主意!

于 2022-01-24T03:28:39.613 回答