转: 原文:https://blog.csdn.net/sld880311/article/details/77854651

-------------------------------------------------------

基本概念
A gateway to userspace。

TUN和TAP设备是Linux内核虚拟网络设备,纯软件实现。
     OS向连接到TUN/TAP设备的用户空间程序发送报文;用户空间程序可像物理口发送报文那像向TUN/TAP口发送报文,在这种情况下,TUN/TAP设备发送(或注入)报文到OS协议栈,就像报文从物理端口收到一样。
链接:

TUN/TAP: The user-space application/VM can read or write an ethernet frame to the tap interface and it would reach the host kernel, where it would be handled like any other ethernet frame that reached the kernel via physical (e.g. eth0) ports. You can potentially add it to a software-bridge (e.g. linux-bridge)

如何工作
     TUN/TAP 为简单的点对点或以太网设备,不是从物理介质接收数据包,而是从用户空间程序接收;不是通过物理介质发送数据包,而是将它们发送到用户空间程序。
     假设您在 tap0 上配置 IPX,那么每当内核向 tap0 发送一个 IPX 数据包时,它将传递给应用程序(例如 VTun)。应用程序加密、压缩数据包,并通过 TCP/UDP 发送到对端。对端的应用程序解压缩、解密接收的数据包,并将数据包写入 TAP 设备,然后内核处理数据包,就像该数据包来自真实的物理设备。
     在Linux内核中添加了一个TUN/TAP虚拟网络设备的驱动程序和一个与之相关的字符设备/dev/net/tun,字符设备tun作为用户空间和内核空间交换数据的接口。
     用户空间的应用程序可以通过这个设备文件来和内核中的驱动程序进行交互,其他操作方式和普通文件操作无异。当内核将数据包发送到虚拟网络设备时,数据包被保存在设备相关的一个队列中,直到用户空间程序通过打开的字符设备tun的描述符读取时,它才会被拷贝到用户空间的缓冲区中,其效果就相当于,数据包直接发送到了用户空间。通过系统调用write发送数据包时其原理与此类似。
     tun/tap驱动程序中包含两部分:字符设备驱动和网卡驱动。利用网卡驱动部分接受来自tcp/ip协议栈的网络分包并发送或者反过来将接收到的网络分包传给协议栈处理。而字符设备驱动部门将网络分包在内核与用户态之间传送,模拟物理链路的数据接受和发送。tun/tap驱动很好的实现了两种驱动的结合。

用途
     用于加密、VPN、隧道、虚拟机等等(encryption, VPN, tunneling,virtual machines)。
     tun/tap设备的用处是将协议栈中的部分数据包转发给用户空间的应用程序,给用户空间的程序一个处理数据包的机会。于是比较常用的数据压缩、加密等功能就可以在应用程序中实现。tun/tap设备最常用的场景是VPN,包括tunnel以及应用层的IPSec等。

tap/tun在libvirt中的应用

VPN

其他
常用命令
root@ubuntu:~# ip tuntap help
Usage: ip tuntap { add | del } [ dev PHYS_DEV ]
[ mode { tun | tap } ] [ user USER ] [ group GROUP ]
[ one_queue ] [ pi ] [ vnet_hdr ] [ multi_queue ]

Where: USER := { STRING | NUMBER }
GROUP := { STRING | NUMBER }
1
2
3
4
5
6
7
8
veth、tun、tap比对

tun 是点对点的设备 , 而 tap 是一个普通的以太网卡设备 。 也就是说 ,tun 设备其实完全不需要有物理地址的 。 它收到和发出的包不需要 arp, 也不需要有数据链路层的头 。 而 tap 设备则是有完整的物理地址和完整的以太网帧 。
TAP (network tap) operates much like TUN however instead of only being able to write and receive layer 3 packets to/from the file descriptor it can do so with raw ethernet packets. You will typically see tap devices used by KVM/Qemu virtualization, where a TAP device is assigned to a virtual guests interface during creation.

TUN(Tunel)设备模拟网络层设备,处理三层报文,如IP报文。TAP设备模型链路层设备,处理二层报文,比如以太网帧。TUN用于路由,而TAP用于创建网桥。

示例(来源于网络)
示例程序
收到tun设备的数据包之后,只打印出收到了多少字节的数据包,其它的什么都不做

#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";

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) {
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
演示
#--------------------------第一个shell窗口----------------------
#将上面的程序保存成tun.c,然后编译
root@ubuntu:~# gcc tun.c -o tun

#启动tun程序,程序会创建一个新的tun设备,
#程序会阻塞在这里,等着数据包过来
root@ubuntu:~# ./tun
Open tun/tap device: tun0 for reading...
Read 84 bytes from tun/tap device
Read 84 bytes from tun/tap device
Read 84 bytes from tun/tap device
Read 84 bytes from tun/tap device

#--------------------------第二个shell窗口----------------------
#启动抓包程序,抓经过tun0的包
root@ubuntu:/home/sunld# tcpdump -i tun0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
02:53:08.840817 IP 192.168.209.138 > 192.168.209.139: ICMP echo request, id 9828, seq 1, length 64
02:53:09.839871 IP 192.168.209.138 > 192.168.209.139: ICMP echo request, id 9828, seq 2, length 64
02:53:10.850205 IP 192.168.209.138 > 192.168.209.139: ICMP echo request, id 9828, seq 3, length 64
02:53:11.851285 IP 192.168.209.138 > 192.168.209.139: ICMP echo request, id 9828, seq 4, length 64

#--------------------------第三个shell窗口----------------------
#./tun启动之后,通过ip link命令就会发现系统多了一个tun设备,
27: tun0: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 500
link/none
#新的设备没有ip,我们先给tun0配上IP地址
root@ubuntu:/home/sunld# ip addr add 192.168.209.138/24 dev tun0
#默认情况下,tun0没有起来,用下面的命令将tun0启动起来
root@ubuntu:/home/sunld# ip link set dev tun0 up

#尝试ping一下192.168.209.0/24网段的IP,
#由于我们的程序中收到数据包后,啥都没干,相当于把数据包丢弃了,
#所以这里的ping根本收不到返回包,
#但在前两个窗口中可以看到这里发出去的四个icmp echo请求包,
#说明数据包正确的发送到了应用程序里面,只是应用程序没有处理该包
root@ubuntu:/home/sunld# ping -c 4 192.168.209.139 -I tun0
PING 192.168.209.139 (192.168.209.139) from 192.168.209.138 tun0: 56(84) bytes of data.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
参考资料
kernel doc tuntap
virtual networking devices in linux
Linux Networking Explained
Tun/Tap interface tutorial
TUN, TAP and Veth - Virtual Networking Devices Explained
虚拟机网卡和linux bridge上tap设备的关系
Linux虚拟网络设备之tun/tap

点赞 3
————————————————
版权声明:本文为CSDN博主「翰霖学院」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sld880311/article/details/77854651

[转]Linux-虚拟网络设备-tun/tap的更多相关文章

  1. 一文总结 Linux 虚拟网络设备 eth, tap/tun, veth-pair

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Linux 虚 ...

  2. 虚拟网卡 TUN/TAP 驱动程序设计原理

    简介 虚拟网卡Tun/tap驱动是一个开源项目,支持很多的类UNIX平台,OpenVPN和Vtun都是基于它实现隧道包封装.本文将介绍tun/tap驱动的使用并分析虚拟网卡tun/tap驱动程序在li ...

  3. 虚拟网卡TUN/TAP 驱动程序设计原理

    昨天韦哥写了<Linux下Tun/Tap设备通信原理>一文,只提到了两个使用Tun的用户进程之间的通信路径,并没有说明Tun虚拟网卡驱动是如何实现的,而正好看到了这里的一篇讲解这方面的文章 ...

  4. 【转】Linux虚拟网络基础——tap

    原文:https://blog.csdn.net/chengqiuming/article/details/80071073 ------------------------------------- ...

  5. 虚拟网卡 TUN/TAP 驱动程序设计原理(经典)

    盗用-收藏 简介 虚拟网卡Tun/tap驱动是一个开源项目,支持很多的类UNIX平台,OpenVPN和Vtun都是基于它实现隧道包封装.本文将介绍tun/tap驱动的使用并分析虚拟网卡tun/tap驱 ...

  6. 云原生虚拟网络 tun/tap & veth-pair

    云原生虚拟网络 tun/tap & veth-pair 转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/684 ...

  7. [转]Linux虚拟网络设备之tun/tap

    转, 原文:https://segmentfault.com/a/1190000009249039 -------------------------------------------------- ...

  8. Linux 虚拟网络设备 veth-pair 详解,看这一篇就够了

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面这篇文章介 ...

  9. Linux 虚拟网络设备详解之 Bridge 网桥

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面几篇文章介 ...

随机推荐

  1. DevOps - 基础设施配置测试工具Serverspec

    1 - Serverspec Serverspec是可以测试基础设施配置的工具,能够验证配置管理工具(Ansible.Puppet.Chef等)的配置结果,可以实现基础设施测试代码化自动化. 测试代码 ...

  2. typescript导入图片报找不到模块的错误

    https://www.cnblogs.com/chen-cong/p/10445635.html images.d.ts: declare module '*.svg' declare module ...

  3. springboot2 设置系统访问的默认首页

    @Configuration public class WebMvcConfig implements WebMvcConfigurer{ @Override public void addViewC ...

  4. 待补充 MySQL必知必会第29章--------数据库维护

    备份数据 由于MySQL数据库是基于磁盘的文件,普通的备份系统和里程就能备份MySQL的数据.但是,由于这些文件总是处于打开和使用状态,普通的文件副本备份不一定总是生效.

  5. 将python工程部署到新服务器(对virtualenv工具进行环境迁移)

    将python工程部署到新服务器(对virtualenv工具进行环境迁移) # 从开发的电脑上导出 pip list 到 requirements.txt 文件pip freeze > requ ...

  6. spring data jpa碰到的坑

    1.不能从别的类的repository那里 执行另一个类的sql,这样映射会失败. 2.有entity,就要有repository,并且还要有id注解 3.还要多表联查未测试,估计要用map去映射出来 ...

  7. redis源码分析(一)-sds实现

    redis支持多种数据类型,sds(simple dynamic string)是最基本的一种,redis中的字符串类型大多使用sds保存,它支持动态的扩展与压缩,并提供许多工具函数.这篇文章将分析s ...

  8. git学习笔记 --分支管理策略

    通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息. 如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的comm ...

  9. 【解决方案】ArcGIS导入要素集后没反应

    内容源自:ArcGIS10.2基础教程(丁华) 书上要求: 1.在“练习”文件夹中新建一个名为“沈阳”的个人地理数据库和名为“shenyang”的要素集,设置地理坐标为“Xi'an 1980”,高程坐 ...

  10. python中通过selenium简单操作及xpath元素定位&轴定位

    浏览器的简单操作 # 导入webdriver模块 # 创建driver对象,指定Chrome浏览器 driver = webdriver.Chrome() # 窗口最大化 driver.maximiz ...