使用多线程时 Scapy 无法嗅探数据包 [英] Scapy fails to sniff packets when using multiple threads

查看:93
本文介绍了使用多线程时 Scapy 无法嗅探数据包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尝试用一个简化的示例来演示我的问题.

I'll try to demonstrate my problem with a simplified example.

以下是一个非常简单的(单线程)数据包嗅探器 (ICMP):

Following is a very simple (single threaded) packet sniffer (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)

这个嗅探器工作得很好,我得到了输出:

This sniffer works just fine and I get the output:

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
...

接下来,我创建一个单独的线程来嗅探数据包,并使用队列在嗅探线程和主线程之间传递捕获的数据包:

Next, I create a separate thread for sniffing packets and use a Queue to communicate the captured packets between the sniffer thread and the main thread:

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() 函数时,如下所示:

This sniffer also works fine and I get the same output as above. However, when I modify the main thread just a little bit so that it uses the send() function between reads from the packet queue as below:

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

然后我得到以下奇怪的输出(过滤器似乎不起作用):

Then I get the following bizarre output (the filter doesn't seem to work):

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
...

三个嗅探器的脚本可以从这里下载.

The script for the three sniffers can be downloaded from here.

我目前的系统配置如下:

My current system configuration is as below:

Python: 2.7.3
Scapy: 2.2.0
OS: Fedora 18

有趣的是,这三个嗅探器在我的旧电脑上都可以正常工作:

Interestingly, all the three sniffers work fine on my older computer:

Python: 2.6.4
Scapy: 2.0.0.10 (beta)
OS: Fedora 13

首先我认为它可能是 Scapy/Python 版本.但即使我在新计算机上安装了完全相同的版本,该行为仍然存在.

First I thought it might be the Scapy / Python versions. But even when I installed the exact same versions on my new computer, the behaviour persisted.

我不确定这是否适合 SO(可能是给 Scapy 的错误报告?).在这种情况下,请原谅.

I'm not entirely sure if this is a question suitable for SO (may be a bug report to Scapy?). Please excuse me in that case.

推荐答案

造成这种情况的主要原因很可能是因为资源锁定.Scapy 的 sniff() 函数可能必须锁定低级网络资源才能嗅探数据包.

The main reason for this is most likely because of resource locks. Scapy's sniff() function probably have to lock on to low-level network resources in order to be able to sniff packets.

延迟两个线程(在启动嗅探器线程之后),您将确保 Scapy 将获得所需的时间.

Delaying the two threads (after starting the sniffer thread) you'll ensure that Scapy will get the time it needs to do so.

要了解我们是如何得出这个结论的,请参阅上面评论部分的讨论.Gl Asiri Rathnayake :)

To see how we came to this conclusion see the discussion above in the comment section. Gl Asiri Rathnayake :)

这篇关于使用多线程时 Scapy 无法嗅探数据包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆