使用 Scapy 的 StreamSocket() mrthod 发送启用 ECN 的 TCP 数据包

网络工程 通讯协议 拥塞
2021-07-07 17:45:55

我试图了解 ECN 标志如何影响发送方的 TCP 拥塞窗口(linux 中的 snd_cwnd 参数)。

为此,我使用 scapy 在 HostA 上生成所需的数据包,将其作为 sr(IP(src='aaaa',dst='bbbb')/TCP(flags=0x050)) 定向到 HostB。

这确实触发了 hostA 向 hostB 发送了一个启用 tcp ecn 的数据包,但是由于 scapy 在用户空间中工作,而不是特别是在 Linux 内核 TCP 中,我无法提取拥塞窗口参数。然后我使用 scapy 的 StraemSocket() 模块将 scapy 连接绑定到 linux TCP 套接字。Hosta = 服务器(aaaa),HostB = 客户端(bbbb)

代码如下: 服务器:

from scapy.all import *
import socket

serversocket = socket.socket()
serversocket.bind(("a.a.a.a",9876))
serversocket.listen(1)
sc,sockname = serversocket.accept()
serverstream=StreamSocket(sc)
serverstream.sr(IP(src='a.a.a.a',dst='b.b.b.b')/TCP(flags=0x050))

客户:

from scpay.all import *
import socket
clientsocket = socket.socket()
clientsocket.connect(("a.a.a.a",9876))
clientstream = StreamSocket(clientsocket)
clientstream.sr(IP(src="b.b.b.b",dst="a.a.a.a")/TCP(flags="S"))

从下面的快照可以看出,带有 ecn 和 cwd 标志的 3 次握手成功(我已经在主机和所有中间路由器上启用了 ecn)。但wireshark 只是没有捕获服务器发送的带有ecn 标记的数据包。我不确定服务器是否发送了数据包,我在这里真的想完了。

缺少启用 ecn 的 tcp 数据包

1个回答

使用 时StreamSocket,发送的数据包通过 TCP 连接发送。在 Scapy 表示法中,当您键入serverstream.sr(IP(src='a.a.a.a',dst='b.b.b.b')/TCP(flags=0x050))(顺便说一句,您可以替换flags=0x050flags="AE")时,它将导致发送如下数据包:

IP(src="a.a.a.a", dst="b.b.b.b") / TCP(flags="PA") / \
    IP(src="a.a.a.a", dst="b.b.b.b")/TCP(flags="AE")

第一IP()/TCP()层不在 Scapy 的控制之下,而是在服务器的网络堆栈控制之下(例如,您不能使用 Scapy 更改那里的标志)。

IP()/TCP()转换为str()对象的第二是 Scapy 制作的数据包(因此您可以完全控制它)。在网络上,对于 Wireshark,数据包只是通过 TCP 传输的原始数据。您可以猜测屏幕截图上显示的第四个和第六个数据包是IP()/TCP()/IP()/TCP()由于数据的长度(40 字节,len(IP()/TCP())返回40)。

您可以从 Wireshark 保存您的捕获(作为 PCAP,而不是 PCAPNG),然后将其加载到 Scapy 中进行解码:

>>> x = rdpcap('your_capture.cap')
>>> PacketList(IP(str(p[TCP].payload)) for p in x
...            if TCP in p and p[IP].len >= 80).show()

如果你想用 Scapy 控制 TCP 选项,那么你必须创建数据包并发送它们sr()(但你必须自己打开连接)。