Spróbuję zademonstrować mój problem za pomocą uproszczonego przykładu.Scapia nie może sniffować pakietów przy użyciu wielu wątków.
Poniżej znajduje się bardzo prosty (pojedynczy gwintowane) sniffer pakietów (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)
to sniffer działa dobrze i mam wyjścia:
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
...
Następnie utworzyć oddzielny Wątek do wąchania pakietów i kolejki do przesyłania przechwyconych pakietów między wątkiem sniffer a głównym wątkiem:
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
Ten sniffer działa również dobrze i mam takie samo wyjście jak powyżej. Jednak, kiedy zmodyfikować główny wątek tylko trochę tak, że wykorzystuje funkcję send()
między odczytuje z kolejki pakietów poniżej:
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
następnie uzyskać następujący wynik dziwaczne (filtr nie wydaje się praca):
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
...
scenariusz dla trzech sniffer można pobrać ze here.
Moja obecna konfiguracja systemu jest jak poniżej:
Python: 2.7.3
Scapy: 2.2.0
OS: Fedora 18
Co ciekawe, wszystkie trzy sniffery działać dobrze na moim starszym komputerze:
Python: 2.6.4
Scapy: 2.0.0.10 (beta)
OS: Fedora 13
Najpierw pomyślałem, że może to być wersje Scapy/Python . Ale nawet gdy zainstalowałem dokładnie te same wersje na moim nowym komputerze, zachowanie utrzymywało się.
Nie jestem do końca pewien, czy jest to pytanie odpowiednie dla SO (może to być zgłoszenie błędu do Scapy?). Proszę wybacz mi w tej sprawie.
Wygląda na to, że znany błąd: http://trac.secdev.org/scapy/ticket/747 –
@ChathurangaChandrasekara: Problem, który napotykam, dotyczy wielowątkowości. Kod działa poprawnie bez wątków. –
@AsiriRathnayake Nie ma to nic wspólnego z faktem, że interfejs sieciowy kończy się w trybie "Premiscious" i że tylko jedno źródło może powiązać ten interfejs? Jeśli nie, czy próbowałeś użyć biblioteki python 'threading' zamiast kolejki? Nie jestem pewien, jak działa system kolejki, ale dzięki 'threading' zyskujesz większą kontrolę nad tym, co robi co najmniej, i możesz trochę trajkotać. – Torxed