2013-04-29 1 views
6

간략한 예를 사용하여 문제를 보여줍니다.여러 스레드를 사용할 때 Scapy가 패킷을 스니핑하지 못합니다.

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) 

이 스니퍼가 잘 작동하고 내가 출력을 얻을 :

다음은 아주 간단한 (단일 스레드) 패킷 스니퍼 (ICMP)입니다

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

다음, 나는 별도의를 만들 쓰레드를 스니핑 (sniffing)하기위한 쓰레드 (thread)와 스니퍼 쓰레드 (sniffer thread)와 메인 쓰레드 (thread) 사이에서 캡쳐 된 패킷을 전달하기 위해 큐 (Queue)를 사용하라 :

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 

이 스니퍼도 정상적으로 작동하며 위와 동일한 결과를 얻습니다. 그런 다음

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 

나는 기괴한 출력 다음 (필터가하지 않는 것 얻을 : 아래와 같은 패킷 큐에서 읽어 사이가 send() 기능을 사용하도록 그러나, 나는 메인 스레드에게 조금 수정 작업) :

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/파이썬 버전 될 줄 알았는데 . 그러나 새 컴퓨터에 똑같은 버전을 설치 했더라도 그 동작은 계속되었습니다.

이 질문이 Scapy에 대한 버그 리포트 일 수 있는지 확실하지 않습니다. 이 경우 실례합니다.

+0

http://trac.secdev.org/scapy/ticket/747 –

+0

@ChathurangaChandrasekara : 문제는 멀티 스레딩과 관련이 있습니다. 코드 스레딩없이 잘 작동합니다. –

+0

@AsiriRathnayake 네트워크 인터페이스가 "Premiscious mode"로 끝나고 하나의 소스 만 해당 인터페이스에 바인드 할 수 있다는 사실과 관련이 없습니다. 그렇지 않다면, 큐 대신에 파이썬'threading' 라이브러리를 사용해 보셨습니까? 나는 큐 시스템이 어떻게 작동하는지 완전히 확신하지는 못하지만,'threading'을 사용하면 최소한 어떤 일을하는지 더 잘 제어 할 수 있습니다. – Torxed

답변

6

이 주된 이유는 리소스 잠금 때문일 가능성이 큽니다. Scapy의 sniff() 기능은 아마도 패킷을 스니핑 할 수 있도록 저수준 네트워크 리소스에 고정되어야합니다.

스니퍼 스레드를 시작한 후 두 개의 스레드를 지연 시키면 Scapy가 필요한 시간을 확보 할 수 있습니다.

우리가 어떻게 결론을 냈는지 보려면 위의 설명 섹션을 참조하십시오. Gl Asiri Rathnayake :)

+0

이 문제를 조사해 주셔서 감사합니다. 이것은 나의 원래의 문제도 해결했다. (이것은 더 복잡한 의사 소통 시나리오이다.) Scapy의 내부에 스레드 안전성 문제가있을 수 있습니다. Scapy의 누군가가이 게시물을 보게됩니다. –

+1

Yw. 만약 내가 그것에 대한 시간을 내가 메일 링리스트에 메모를 보낼거야 누군가가 잘하면이 메모 걸릴 것입니다 :) – Torxed

관련 문제