设置IP头的标志字段
我有一个简单的Python脚本,它使用socket模块来发送UDP数据包。这个脚本在我的Windows电脑上运行得很好,但在我的Ubuntu Linux电脑上,发送的数据包稍微有点不同。在Windows上,IP头中的标志字段是零,但在Linux上用同样的代码创建的数据包,标志字段却是4。我想修改我的脚本,让它在Windows和Linux上表现一致。
有没有办法在socket模块中控制标志字段?还是说这是我需要在Linux上更改的设置?
3 个回答
1
你可以试试construct,它可能能帮你解决问题。
6
我最后走的这条路是这样的。我跟着SashaN在D.Shwley的回答评论中发的链接,了解了一下为什么Linux的UDP数据包会设置“不要分片”这个标志。结果发现,这和PMTU发现有关。简单来说,你可以通过在Python中使用socket对象的setsockopts函数,来清除UDP数据包中的“不要分片”标志。
import socket
IP_MTU_DISCOVER = 10
IP_PMTUDISC_DONT = 0 # Never send DF frames.
IP_PMTUDISC_WANT = 1 # Use per route hints.
IP_PMTUDISC_DO = 2 # Always DF.
IP_PMTUDISC_PROBE = 3 # Ignore dst pmtu.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("10.0.0.1", 8000))
s.send("Hello World!") # DF bit is set in this packet
s.setsockopt(socket.SOL_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT)
s.send("Hello World!") # DF bit is cleared in this packet
2
我猜这个标志字段实际上是设置为2,也就是二进制的010,而不是4,因为标志等于4是一个无效的IP数据包。记住,标志是IP头部中的一个3位值。我预计会看到UDP数据报的标志值是2,这表示“不要分片”。
至于你的问题,我认为没有办法直接设置IP标志,除非你使用原始套接字。其实也不用太担心,因为大多数应用程序并没有太多理由去直接修改IP或者UDP/TCP的头部。