疫情下的远程办公:理解Linux虚拟网络设备之tun/tap

Table of Contents

VPN TUN

TUN编程

源代码

编译

测试运行

执行程序,生成虚拟设备

为tun设备分配IP地址

ping tun设备



VPN TUN

  1. 应用程序A是一个普通的程序,通过socket A发送了一个数据包,假设这个数据包的目的IP地址是192.168.3.1

  2. socket将这个数据包丢给协议栈

  3. 协议栈根据数据包的目的IP地址,匹配本地路由规则,知道这个数据包应该由tun0出去,于是将数据包交给tun0

  4. tun0收到数据包之后,发现另一端被进程B打开了,于是将数据包丢给了进程B

  5. 进程B收到数据包之后,做一些跟业务相关的处理,然后构造一个新的数据包,将原来的数据包嵌入在新的数据包中,最后通过socket B将数据包转发出去,这时候新数据包的源地址变成了eth0的地址,而目的IP地址变成了一个其它的地址,比如是10.33.0.1.

  6. socket B将数据包丢给协议栈

  7. 协议栈根据本地路由,发现这个数据包应该要通过eth0发送出去,于是将数据包交给eth0

  8. eth0通过物理网络将数据包发送出去

TUN编程

源代码

/**
 * TUN/TAP编程示例
 */
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <linux/if_tun.h>
#include <stdlib.h>
#include <stdio.h>
 
int tun_alloc(int flags)
{
 
    struct ifreq ifr;
    int fd, err;
    char *clonedev = "/dev/net/tun";
 
    //打开tun设备
    if ((fd = open(clonedev, O_RDWR)) < 0) {
        return fd;
    }
 
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = flags;
 
    if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
        close(fd);
        return err;
    }
 
    printf("Open tun/tap device: %s for reading...\n", ifr.ifr_name);
 
    return fd;
}
 
int main()
{
 
    int tun_fd, nread;
    char buffer[1500];
 
    /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
     *        IFF_TAP   - TAP device
     *        IFF_NO_PI - Do not provide packet information
     */
    tun_fd = tun_alloc(IFF_TUN | IFF_NO_PI);
 
    if (tun_fd < 0) {
        perror("Allocating interface");
        exit(1);
    }
 
    while (1) {
        //从tun设备读取数据
        nread = read(tun_fd, buffer, sizeof(buffer));
        if (nread < 0) {
            perror("Reading from interface");
            close(tun_fd);
            exit(1);
        }
 
        printf("Read %d bytes from tun/tap device\n", nread);
    }

    return 0;
}

编译

# gcc tun.c -o tun

测试运行

执行程序,生成虚拟设备

为tun设备分配IP地址

ping tun设备

尽管在网段192.168.3.XX或192.168.4.XX中除去192.168.3.11和192.168.4.11两个IP地址外,其他不存在(因为我为本地,确定不存在其他IP地址),但是根据路由,ping发出去的报文仍需要通过tun设备进行发送,如下图

发布了569 篇原创文章 · 获赞 279 · 访问量 49万+

猜你喜欢

转载自blog.csdn.net/Rong_Toa/article/details/104228483
今日推荐