【发布时间】:2019-01-09 17:35:09
【问题描述】:
我有一个简单的 udp 服务器/客户端设置,我从客户端发送消息并将其打印到服务器上。这适用于常规 IP 数据包,但是当我向数据包添加 IP 选项标头时未收到消息,即使我可以使用 scapy 嗅探数据包。 这是没有 IP 选项的数据包
###[ Ethernet ]###
dst = 00:04:00:00:04:01
src = 00:aa:00:02:00:04
type = 0x800
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 47
id = 1
flags =
frag = 0L
ttl = 61
proto = udp
chksum = 0x62f4
src = 10.0.2.101
dst = 10.0.4.101
\options \
###[ UDP ]###
sport = 10001
dport = 3478
len = 27
chksum = 0x2bd1
###[ Raw ]###
load = 'message from a game'
这是带有 IP 选项标头的数据包:
###[ Ethernet ]###
dst = 00:04:00:00:04:01
src = 00:aa:00:02:00:04
type = 0x800
###[ IP ]###
version = 4L
ihl = 8L
tos = 0x0
len = 59
id = 1
flags =
frag = 0L
ttl = 61
proto = udp
chksum = 0x5fe8
src = 10.0.2.101
dst = 10.0.4.101
\options \
|###[ IPOption ]###
| copy_flag = 1L
| optclass = control
| option = 31L
| length = 12
| value = '\x00\x01\x00\x00RTGAME'
###[ UDP ]###
sport = 10001
dport = 3478
len = 27
chksum = 0x2bd1
###[ Raw ]###
load = 'message from a game'
这里是 UDP 服务器:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', args.port))
while True:
try:
data, addr = sock.recvfrom(1024)
print("received: %s" % data)
except KeyboardInterrupt:
sock.close()
break
我已经被这个问题困扰了几天,如果有人能解决这个问题,我会很高兴的。
谢谢
【问题讨论】:
-
只是为了确认;当您说“嗅探”时,我认为您的意思是在运行“服务器”代码的同一主机上?即它都是本地主机或通过网络实现的。我假设您使用
AF_PACKET来查看较低层,但是如果您使用AF_INET系列会发生什么 -
正确。我编写了一个单独的程序来使用 scapy 嗅探数据包,并在与 udp 服务器相同的主机上运行它。所以数据包确实到达了服务器,但不知何故没有收到。 AF_PACKET 部分只是一个错字。我已经尝试过了,但它也没有工作。现在只使用 AF_INET,我已经更新了问题以反映这一点
-
首先,我认为这与python没有任何关系。你可以很容易地使用
nc -l -u 3478(并删除python标签)。这似乎可能是特定于操作系统的问题(假设接收到的数据包确实有效)。你没有说你正在使用什么操作系统;那会有所帮助。查看 linux 内核源代码,一方面,我看不出带有(未知)IP 选项的相同 UDP 数据包不会传送到您的服务器的任何原因(同样,如果数据包有效)。我不只是用 scapy 嗅探,而是用wireshark 嗅探,并确保wireshark 认为数据包是有效的。 -
@DancingHippo 我认为这与您的环境有关……我可以发送具有相同 IP 选项集的数据包(在 OSX 下使用 Python 3.7.1 进行测试)并且类似的 Python“服务器”代码会看到数据包正如我所料。