我會嘗試用簡單示例演示我的問題。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
...
三個嗅探器的腳本可以從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的錯誤報告?)。在這種情況下請原諒我。
看起來像一個已知的bug:http://trac.secdev.org/scapy/ticket/747 – 2013-05-01 04:03:24
@ChathurangaChandrasekara:我面臨的問題與多線程有關。該代碼工作正常,無需線程。 – 2013-05-01 07:21:27
@AsiriRathnayake這不會發生與網絡接口最終處於「Premiscious模式」並且只有一個源可以綁定到該接口的事實有關?如果沒有,你是否嘗試過使用python'threading'庫而不是隊列?我並不完全確定隊列系統是如何工作的,但是通過'線程',你至少可以控制什麼時候發生什麼,你可以稍微鼓掌一下。 – Torxed 2013-05-06 13:33:36