我正在尝试将 udp 数据包发送到本地 IP 地址。这是我的示例代码:
from scapy.all import *
if __name__ == "__main__":
send(IP(dst="127.0.0.1")/UDP(sport=19600,dport=39600)/"abc")
我已经启动 netcat 来捕获我要发送的内容:
nc -ul 39600
然后我正在执行代码:
python3 example_scapy_send.py
监听网络猫没有收到任何信息。 同时我启动了wireshark,我可以看到数据包已发送。
如果我使用 netcat 发送数据包,它就会到达监听的 netcat。
usr@dev:/home/usr# nc -u 127.0.0.1 39600
test
我能看到的唯一区别是,在第 2 层 - 使用 scapy 发送时目标地址是多播/广播,而使用 netcat 发送时目标地址是单播。但这不是我能控制的。
如果我使用 scapy 将相同的数据包发送到网络上的另一个 IP(另一台主机),该数据包会被接收(由 netcat)。因此,仅当我发送到本地地址时,此问题才适用。使用任何本地 IP 进行测试。不仅仅是127.0.0.1。我还使用 sendp 和 sr scapy 函数进行了测试,但结果是相同的。
更多:如果我启动了另一个 scapy 脚本来监听 UDP/39600(而不是 netcat),我可以看到/我正在接收我发送的数据包。
有什么问题吗?
在 ubuntu/scapy 2.5/python 3.8 下完成的测试
最佳答案
The loopback interface is a very special interface. Packets going through it are not really assembled and disassembled. The kernel routes the packet to its destination while it is still stored an internal structure. What you see with
tcpdump -i lo
is only a fake to make you think everything is normal. The kernel is not aware of what Scapy is doing behind his back, so what you see on the loopback interface is also a fake. Except this one did not come from a local structure. Thus the kernel will never receive it. On Linux, in order to speak to local IPv4 applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems than Linux)
因此您可能需要在发送数据包之前添加行:
conf.L3socket = L3RawSocket
在你的脚本中。这样一切都应该可以正常工作。至少在我的环境中效果很好。
关于python - 使用 python 和 scapy 发送数据包到本地地址不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75312602/