Scapy не может прослушивать пакеты при использовании нескольких потоков

Попробую продемонстрировать мою проблему на упрощенном примере.

Ниже приведен очень простой (однопоточный) анализатор пакетов (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
...

Скрипт для трех снифферов можно скачать сВот.

Моя текущая конфигурация системы, как показано ниже:

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?). Пожалуйста, извините меня в этом случае.

Ответы на вопрос(1)

Ваш ответ на вопрос