双绞线:隧道和网络监听

在 Linux 上,Twisted Pair 支持特殊的 tuntap 网络接口类型。此功能允许您与原始套接字交互(例如,发送或接收 ICMP 或 ARP 流量)。它还允许创建模拟网络。本文档不会涵盖这些平台提供的功能的详细信息,但会解释如何使用与它们交互的 Twisted Pair API。在阅读本文档之前,您可能需要熟悉 Linux tuntap(如果您还没有这样做的话)(好的在线资源很少,但您可能会发现 linux tuntap 教程 的谷歌搜索结果很有帮助)。

Tuntap 端口

The twisted.pair.tuntap.TuntapPort 类是进入 tun/tap 功能的入口点。此类使用应用程序提供的协议对象进行初始化,并将该对象与系统上的 tun 或 tap 设备关联。如果协议提供 twisted.pair.ethernet.IEthernetProtocol,则它将与 tap 设备关联。否则,协议必须提供 twisted.pair.raw.IRawPacketProtocol,它将与 tun 设备关联。

from zope.interface import implementer
from twisted.pair.tuntap import TuntapPort
from twisted.pair.ethernet import EthernetProtocol
from twisted.pair.rawudp import RawUDPProtocol
from twisted.internet import reactor

# Note that you must run this example as a user with permission to open this
# device.  That means run it as root or pre-configure tap0 and assign ownership
# of it to a non-root user.  The same goes for tun0 below.

tap = TuntapPort(b"tap0", EthernetProtocol(), reactor=reactor)
tap.startListening()

tun = TuntapPort(b"tun0", RawUDPProtocol(), reactor=reactor)
tun.startListening()

在上面的示例中,两个协议连接到网络:一个连接到 tap 设备,另一个连接到 tun 设备。此示例中使用的 EthernetProtocolIEthernetProtocol 的一个非常简单的实现,它除了根据它接收的每个以太网帧的标头中找到的协议分派到其他协议之外,什么也不做。 RawUDPProtocol 类似 - 它根据接收到的 IP 数据报的 UDP 端口分派到其他协议。此示例不会执行任何操作,因为没有将应用程序协议添加到 EthernetProtocolRawUDPProtocol 实例(更不用说反应器没有启动)。但是,它应该让您了解 tun/tap 功能如何融入 Twisted 应用程序。

通过这两个协议的行为,您可以看到 tap 和 tun 设备之间的主要区别。两个中较低级别的 tap 设备连接到以太网层的网络堆栈。当 TuntapPort 与 tap 设备关联时,它会将完整的以太网帧传递给其协议。较高级别的 tun 设备在将数据传递给应用程序之前会剥离以太网层。这意味着与 tun 设备关联的 TuntapPort 通常会将 IP 数据报传递给其协议(尽管如果您的网络用于传送非 IP 数据报,那么它可能会传递这些数据报)。

Both IEthernetProtocol and IRawSocketProtocol are similar to twisted.internet.protocol.DatagramProtocol . 数据报,无论是以太网还是其他,都会传递到协议的 datagramReceived 方法。相反,协议与具有 write 方法的传输关联,该方法接受要注入网络的数据报。

您可以在 ../examples/pairudp.py 示例中看到一些此功能的示例。