tun/tap 驱动程序实现了虚拟网卡的功能,tun表示虚拟的是点对点设备,tap表示虚拟的是以太网设备,这两种设备针对网络包实施不同的封装。利用tun/tap 驱动,可以将tcp/ip协议栈处理好的网络分包传给任何一个使用tun/tap驱动的进程,由进程重新处理后再发到物理链路中。

开源项目openvpn (http://openvpn.sourceforge.net)和Vtun(http://vtun.sourceforge.net)都是利用tun/tap驱动实现的隧道封装。

一. Tun/Tap驱动程序工作原理

在linux下,要实现内核空间和用户空间数据的交互,有多种方式:可以通用socket创建特殊套接字,利用套接字实现数据交互;通过proc文件系统创建文件来进行数据交互;还可以使用设备文件的方式,访问设备文件会调用设备驱动相应的例程,设备驱动本身就是内核空间和用户空间的一个接口,Tun/tap驱动就是利用设备文件实现用户空间和内核空间的数据交互。

用户空间的设备节点/dev/net/tun用于读写TUN/TAP设备,内核中TUN/TAP设备在发送数据包时,将数据包发送到与/dev/net/tun文件描述符相关联的套接口,用户空间就可从设备节点读取数据。用户空间程序向/dev/net/tun文件描述符写入数据时,TUN/TAP驱动调用内核的数据包接收函数(如netif_rx)将接收到的数据包送入网络协议栈,就像数据包是从物理网络中接收的一样。

Linux内核的TUN/TAP虚拟设备,不同于内核的其它设备,其发送和接收数据包都在网络协议栈内部完成,发送的数据包并不会离开协议栈进入到物理网络中,同样,也不会接收到从物理网络中进入协议栈的数据包。

    |-----------|   |--------------------------|    |    |--------------------------|    |-----------|
| | | | | | | | |
| apps | | |---- tunnel ----| | | | |---- tunnel ----| | | apps |
| | | | | | | | | | | | |
|-----------| |------------| |--------| | |--------| |------------| |-----------|
192.168.1.0/ |/dev/net/tun| | socket | | | socket | |/dev/net/tun| 192.168.1.0/
|------------|----|--------| | |--------|----|------------|
| |
|----19.1.1.0/---| --------------------------------------------------------------------------------------------------- Linux内核网络协议栈 (ip route add 0.0.0.0/ dev tun0)

图中左侧隧道处理程序从/dev/net/tun文件描述符读取网络应用发出的数据包,经过处理,比如加密,之后通过套接口发往远端(19.1.1.0网络)。图中右侧隧道处理程序通过套接口接收到数据包之后,经过处理,比如解密,之后写入/dev/net/tun文件描述符中,网络应用程序将从内核中接收到原始的数据包。当右侧网络应用回复数据包时,又会沿着原路返回左侧应用。

从结构上来说,Tun/tap驱动并不单纯是实现网卡驱动,同时它还实现了字符设备驱动部分。以字符设备的方式连接用户空间和内核空间。下面是示意图:

aaarticlea/jpeg;base64,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QtU9jbAZN8Wsu4oEab+x9U3h9TP/AALtKFuHhFKEQ/jUOy9gH9taHCZIzO6ZyQc2+Byy3TGzDt7Wi1bYUY56RrvuH7P/AKX4E/4eFf1nm1//AGhLchqc4jhO8OJ4GGR+YSq3YWAjLA0Pbodl7BKMSG6eunrp66eunrp66ey6cy6cy6ey6eunrp66eunrp66eunrp6wv9709dPXT109dPXT109dPXT109dPXT109dPXT109Sofp8K/rPPVuhH018SfTw0THYNYBB2TzlKNd5hFXJIsPY1ZastWVB/9lqy1ZastWWrLVlqy1ZastWWrLVlqy1ZastWWrLVlqy1ZastWWrLVlqy1ZastWWv/JastWWrLVlqy1ZastWWrLVlqy1ZastWWrLVlJ22eFf1urLVkdpSEes0/DzBOQxxc89WWrI9Ms34rDlrAhWFqy1ZastWWreZhsYPpwC9OV16crqv4CAwPTldenK69OV16crr05XXpyuvTldenK69OV16crr05XXpyuvTldenK69OV16crr05XXpyuvTldenK69OV16crr05XXpyuvTldenK69OV16crroIMr05XXpyuvTldenK69OV16crr05XXpyuvTldenK69OV16crr05XXpyuvTldenK6f8A09XZqngobVX05XXpyuvTldenK69OV16crr05XXpyuvTldenK69OV16crr05XXpyuvTldenQKENkPhodl8Tu0WyArICsgKyArICsgKyArICsgKyArICsgKyArICsgKyArICsgKyArICsgK5hdRyArICsgKyArICsgKyArICsgKyArICsgKyArICsgKyAqRw7fDCjj4dkBWQFZAVkBWQFZAVkBTO0m9vkgy5RrlGqJINT5RrlGmnF/gs/Y2strLay2strLay2strLay2strLay2strLay2strLay2strLay0bqW1ltZbWW1ltZbWW1ltZbWW1ltZbWW1ltZbWW1lKLbPCmbpu1ltZbWW1ltZbWW1lV7f2wjg8eIa4hriGuIa4hqcIxL52fsfgmswAsmDR546juhIiWBh8RlcFCbSZ45TcMZRm3M7QgWM4tb1COfJH2J/w8K/rPjq9v7df+Gvz3My1Wq1Rfu+dn7H4PiTO/h9yMpRYsJqmBp1LUX53HzX4DiMY/nCt+qMSTxRPGVUcdPDas98PYn/Dwr+s+Or2/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n6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tmn6c0/Tkn72L//aAAwDAQACAAMAAAAQsMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMs888888888880888888888w08888888880888A804w8ww08UA8w080888UA8004w08488888A8oUoI0I08UAwMswMYoIUUMsI08YsM48888AosYoYQIM8UA88UE8A88UA888EIc8888888A8c8cc8888UA88sMsc88UA888cMc8888888M4888gQw0w8c888k0888sM8oNU8888888888U888WhAJxtzzzzxzzzzzzzzXUkow0c888Y808888888888888s88888884X0c8s4888UwwY088wwwwwwwwwwkwwwwwwwwJwwww88888UMoM8oU8888888EEkYk8U888o9U88888888EAQQ8oc8888888888sc88888s5c88488888Aw4g88IAMEMA88884c888888o9U88M88888ov+ys/OSvuCCv+O/fd888888o9Uw4IkI88888U04ww084088888888w4808o9U8cc8M88888UdIv9pyg/8X088884a+3HJsX2/G08888888ASX3Bof2uY5c8888oQSm8KzgQyz08888888Ab4FzEU1acp88888oSo2DaYH7rUU8888888ACJi+Ke/Ddp88888oX4xFnzuvP0U8888888EXDwxa713Vv8APPPPKDJ6djVJSdiVPPPPPPPBMIQ0qcfPI9fPPPPPDz/z+z2LNENONNMPPPLDDDDDPPPPPPPPPPPPPPPPHKKNODJPLLPPPPPOPMPOPMPPPOPMMPPMPNKHPFMNCFIOJPPPPPPPPPPPPPPPPAHCNHMPPPPKJLJIILDFPPPPPPPPPPPPPPPPPHDHHPPPPPPPPPPPPPDGP//EACURAAMAAgEDBQADAQAAAAAAAAABESExQTBRcRAgUGGRQHChgf/aAAgBAwEBPxD+2Kqn8N/8P4DKUpX2K+xSlKX6KUpSlKU5+D5+D5+D5+D5+D56cSQadiLYhJnBVJCOxFsREkIkhFsQktiI7DR8EWwSdiJIIelOhz8Hz1d2n2GrkV0xvz8Gvhibwxjhidwx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" alt="" name="图片 3" width="420" height="294" align="bottom" border="0" />

Tun/tap 驱动程序中包含两个部分,一部分是字符设备驱动,还有一部分是网卡驱动部分。利用网卡驱动部分接收来自TCP/IP协议栈的网络分包并发送或者反过来将接收到的网络分包传给协议栈处理,而字符驱动部分则将网络分包在用户空间和内核空间之间传送,模拟物理链路的数据接收和发送。Tun/tap驱动很好的实现了两种驱动的结合。

二、Tun/Tap网卡创建

1确认内核是否支持tun/tap

[root@hunterfu]# modinfo tun

filename: /lib/modules/2.6.34.7-.fc13.i686.PAE/kernel/drivers/net/tun.ko

alias: char-major--

license: GPL

author: (C) - Max Krasnyansky <maxk@qualcomm.com>

description: Universal TUN/TAP device driver

srcversion: 880DE258930FE60D765B735

depends:

vermagic: 2.6.34.7-.fc13.i686.PAE SMP mod_unload 

2. 加载内核模块

# modprobe tun

# lsmod | grep tun

     tun   

执行以上命令后,出现如上输出,说明模块加载成功。

3.创建和配置虚拟网卡

确认是否有tunctl命令,如果没有通过yum安装即可。

# yum install tunctl

创建虚拟网卡设备

[root@hunterfu ~]# tunctl -t tap0 -u root

设置虚拟网卡

# ifconfig tap0 192.168.0.1 netmask 255.255.255.0 promisc

经过如上操作后,虚拟网卡已经建立和配置好了。

参考:

    1. linux下TUN/TAP虚拟网卡的使用

    2. Linux内核TUN/TAP设备驱动

    3. Linux内核网络设备——tun、tap设备

tun/tap设备_虚拟网卡的更多相关文章

  1. Linux下Tun/Tap设备通信原理

    Tun/Tap都是虚拟网卡,没有直接映射到物理网卡,是一种纯软件的实现.Tun是三层虚拟设备,能够处理三层即IP包,Tap是二层设备,能处理链路层网络包如以太网包.使用虚拟网络设备,可以实现隧道,如O ...

  2. Linux中的TUN/TAP设备

    今天才发现这家伙...怎么讲...深以为耻.晚上的任务是加深对它的了解,就这么定了. 1. General questions.1.1 What is the TUN ?  The TUN is Vi ...

  3. 【转】TUN/TAP虚拟网络设备

    转: 原文:https://www.cnblogs.com/wyzhou/p/9286864.html ------------------------------------------------ ...

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

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

  5. TUN/TAP/VETH

    TUN/TAP虚拟网络设备为用户空间程序提供了网络数据包的发送和接收能力.他既可以当做点对点设备(TUN),也可以当做以太网设备(TAP). TUN/TAP虚拟网络设备的原理: 在Linux内核中添加 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 蓝桥杯 ——无重复组合——C++

    问题描述: 求任意长度的(ABCD.....)全部n=0,1,2 ....组合情况(n小于等于串的长度) 解决思路: 如果串的长度固定,n的值固定循环嵌套 在这里以深度优先形成一棵树,如下图: 源代码 ...

  2. HNOI 2017

    题目链接 我还是按bzoj AC数量排序做的 4827 这个其实如果推一下(求每个值)式子会发现是个卷积,然后FFT就好了 4826 记不太清了,可以求出每个点左右第一个比他的的点的位置,将点对看成平 ...

  3. error LNK2001: unresolved external symbol _main

    想运行一个网上下载的opengl离屏渲染(渲染到纹理FBO)的程序,然后一直报错 error LNK2001: unresolved external symbol _main 解决了一下午终于弄明白 ...

  4. PAT基础6-6

    6-6 求单链表结点的阶乘和 (15 分) 本题要求实现一个函数,求单链表L结点的阶乘和.这里默认所有结点的值非负,且题目保证结果在int范围内. 函数接口定义: int FactorialSum( ...

  5. Vue(十六)vue-router路由

    一. vue-router路由   1. 简介 使用Vue.js开发SPA(Single Page Application)单页面应用 根据不同url地址,显示不同的内容,但显示在同一个页面中,称为单 ...

  6. JAVA自学笔记03

    1.三目运算符 1)格式:(关系表达式)?表达式1:表达式2 true则执行表达式1,false则执行表达式2 @ 例题1 :求两数中的较大值 System.out.println(x>y?x: ...

  7. 浏览器模式&用户代理字符串(IE)

    问题问题描述今天在做项目的时候,QA部门提了一个Bug,在一个搜索列表中,搜索栏为空时刷新页面,却触发了搜索功能,并且列表显示出<未搜索到结果> 环境IE11 问题原因 QA的IE11用户 ...

  8. CSS魔法堂:改变单选框颜色就这么吹毛求疵!

    前言  是否曾经被业务提出"能改改这个单选框的颜色吧!让它和主题颜色搭配一下吧!",然后苦于原生不支持换颜色,最后被迫自己手撸一个凑合使用.若抛开input[type=radio] ...

  9. 通过IntelliJ IDEA和Maven命令查看某个jar包是怎么引入的

    发现打包的时候引入的jar包有几百个,如果想知道某个jar包是如何引入的,可以 看Maven Projects,点开某个Module的Dependencies 一层一层展开就可以了 可以直接输入名称高 ...

  10. C# 获取字符串字节长度

    一.C# 获取字符串字节长度 1.在C# 语言中使用string 字符串Unicode 编码 2.在C#语言中常用汉字 占 3个字节 方式1:使用默认编码类获取字节长度 Console.WriteLi ...