当我们创建 tun 虚拟接口时,我们使用read
和write
从网络堆栈读取和写入数据包。我的问题是,当我们使用 时.read
,我们实际上是在读取传出数据包(由机器应用程序创建以发送到另一个网络的数据包)还是传入数据包(到达机器的数据包)?
答案1
tun/tap 接口是在应用程序和内核网络堆栈之间传递数据包的方式。
创建点击界面:
ip tuntap add dev tun101 mode tun
ip link set up dev tun101
ip a add 192.0.2.1/24 dev tun101
让我们从分配给 tun101 接口的子网 ping 一些地址。
ping 192.0.2.2
发生了什么?
- ping 创建套接字,构建 icmp 回显请求数据包并将其写入套接字。
- 内核通过套接字接收来自 ping 的 icmp 回显请求数据包,确定此数据包的路由并将数据包传递到 tuntap 驱动程序。
- 对于网络堆栈来说,这些数据包源自本地并传出到外部。
- tuntap 驱动程序接收 icmp 回显请求数据包并将其发送到您的应用程序。
- 您的应用程序调用该
read
函数并在相应的内存缓冲区中获取 icmp 回显请求数据包。 - 您的应用程序为收到的请求构建 icmp echo 回复数据包。
- 您的应用程序使用该函数编写这些回复
write
。 - tuntap 驱动程序从您的应用程序接收数据包并将其进一步传递到网络堆栈。
- 对于内核网络堆栈来说,这些数据包是从外部传入的。
- 内核堆栈确定这些数据包的地址为主机本身,并将其发送到由 ping 创建的套接字中。
- ping 从套接字读取数据,计算延迟并显示收到的答案。
应用程序中的读取操作意味着读取数据包,这些数据包已被tun
内核网络堆栈发送到相应的接口。写入操作意味着将数据包从您的应用程序发送到内核网络堆栈。