我将尝试通过一个简化的示例来演示我的问题。
以下是一个非常简单的(单线程)数据包嗅探器(ICMP):
from scapy.all import *
m_iface = "wlan0"
m_dst = "192.168.0.1"
def print_summary(pkt):
print pkt.summary()
def plain_sniff():
sniff(iface = m_iface, count = 10, filter = "icmp and src {0}".format(m_dst), prn = print_summary)
这个嗅探器工作得很好,我得到了输出:
WARNING: No route found for IPv6 destination :: (no default route?)
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0 / Raw
...
接下来,我创建一个单独的线程来嗅探数据包,并使用队列在嗅探器线程和主线程之间传递捕获的数据包:
from threading import Thread
from Queue import Queue, Empty
from scapy.all import *
m_iface = "wlan0"
m_finished = False
m_dst = "192.168.0.1"
def print_summary(pkt):
print pkt.summary()
def threaded_sniff_target(q):
global m_finished
sniff(iface = m_iface, count = 10, filter = "icmp and src {0}".format(m_dst), prn = lambda x : q.put(x))
m_finished = True
def threaded_sniff():
q = Queue()
sniffer = Thread(target = threaded_sniff_target, args = (q,))
sniffer.daemon = True
sniffer.start()
while (not m_finished):
try:
pkt = q.get(timeout = 1)
print_summary(pkt)
except Empty:
pass
这个嗅探器也可以正常工作,我得到与上述相同的输出。但是,当我稍微修改主线程,以便它在从数据包队列读取之间使用
send()
函数时,如下所示:def threaded_sniff_with_send():
q = Queue()
sniffer = Thread(target = threaded_sniff_target, args = (q,))
sniffer.daemon = True
sniffer.start()
while (not m_finished):
send(IP(dst = m_dst) / ICMP()) # Here
try:
pkt = q.get(timeout = 1)
print_summary(pkt)
except Empty:
pass
然后,我得到以下奇怪的输出(过滤器似乎不起作用):
WARNING: No route found for IPv6 destination :: (no default route?)
Sent 1 packets.
Ether / ARP who has 192.168.0.1 says 192.168.0.9
Sent 1 packets.
Ether / ARP is at a0:21:b7:1a:7a:db says 192.168.0.1
Sent 1 packets.
Ether / IP / ICMP 192.168.0.9 > 192.168.0.1 echo-request 0
Sent 1 packets.
Ether / IP / ICMP 192.168.0.1 > 192.168.0.9 echo-reply 0
...
可以从here下载三个嗅探器的脚本。
我当前的系统配置如下:
Python: 2.7.3
Scapy: 2.2.0
OS: Fedora 18
有趣的是,这三个嗅探器在我的旧计算机上都能正常工作:
Python: 2.6.4
Scapy: 2.0.0.10 (beta)
OS: Fedora 13
首先,我认为可能是Scapy/Python版本。但是,即使我在新计算机上安装了完全相同的版本,该行为仍然存在。
我不完全确定这是否是适合SO的问题(可能是向Scapy报告错误?)。在这种情况下,请原谅。
最佳答案
造成这种情况的主要原因很可能是由于资源锁定。 Scapy的sniff()
函数可能必须锁定低级网络资源才能嗅探数据包。
延迟两个线程(在启动嗅探器线程之后),您将确保Scapy将获得这样做所需的时间。
要了解我们如何得出这个结论,请参见上面注释部分中的讨论。
Gl Asiri Rathnayake :)
关于python - 使用多个线程时,Scapy无法嗅探数据包,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16279661/