在继承自threading.Thread()的类中使用Scapy的sniff()

1 投票
1 回答
4212 浏览
提问于 2025-04-18 12:39

我在使用Scapy的sniff()函数时遇到了一个奇怪的问题。

这是我的类的样子:

    from scapy.all import *
import sys
import datetime
import Queue
from threading import Thread

class packet_sniffer(Thread):
  def __init__(self,pass_queue):
    super(packet_sniffer,self).__init__()
    print 'Packet sniffer started'
    self.queue=pass_queue
    self.device_dict={}
    self.not_an_ap={}


  def PacketHandler(self,pkt):
    if pkt.haslayer(Dot11):
      sig_str = -(256-ord(pkt.notdecoded[-4:-3]))
      mac_addr=""
      ssid=""
      try:
        mac_addr=pkt.addr2
        ssid=pkt.info
      except:
        return
      if self.device_dict.has_key(pkt.addr2) and pkt.info!=self.device_dict[pkt.addr2]:
        output= "DIS MAC:%s RSSI:%s " %(pkt.addr2,sig_str)
        print output
        self.device_dict.pop(pkt.addr2)
        self.not_an_ap[pkt.addr2]=pkt.info
        self.queue.put(output)
      elif pkt.info=="" or pkt.info=="Broadcast":
        output= "DIS MAC:%s RSSI:%s " %(pkt.addr2,sig_str)
        print output
        self.queue.put(output)
      else:
        pot_mac=self.not_an_ap.get(pkt.addr2)
        if pot_mac == None:
          self.device_dict[pkt.addr2]=pkt.info

    def run(self):
      sniff(iface="mon.wlan0",prn=self.PacketHandler)

当我从我的线程管理类调用这个代码时,它并不工作:

编辑:我所说的“不工作”是指sniff要么没有运行,要么没有调用PacketHandler。没有错误信息输出,程序的其他部分正常继续运行。

currentQueue=Queue()

#object setup
print'Initialising sniffer'
packet_sniffer_instance=packet_sniffer(currentQueue)
packet_sniffer_instance.daemon=True
packet_sniffer_instance.start()
time.sleep(1)

print'Finished initialising sniffer'

我在看了这个帖子后加了sleep函数:Scapy无法嗅探

但是,当我把sniff调用移到__init__()函数时,它可以工作,但之后由于packet_sniffer类无限卡在__init__()函数中,导致无法调用后续的线程。

我在Python编程方面还是比较新手(整体上我不是新手,我有很多经验),所以我可能在做一些非常基础的事情时出错了。

谢谢大家。

詹姆斯。

1 个回答

2

看起来,只要把类的结构调整一下,把 run 方法放在 __init__() 方法下面,就解决了这个问题。我还停止使用线程类,改用了多进程类,这个类是在线程类的基础上构建的,但它能让程序同时处理更多的任务。

最终的类看起来是这样的:

from scapy.all import *
import sys
import datetime
import Queue
from multiprocessing import Process

class packet_sniffer(Process):
  def __init__(self,pass_queue):
    super(packet_sniffer,self).__init__()
    print 'Packet sniffer started'
    #self.target=self.monitor()
    self.queue=pass_queue
    self.device_dict={}
    self.not_an_ap={}
    print 'END'

  def run(self):
    sniff(iface="en1",prn=self.PacketHandler)

  def PacketHandler(self,pkt):
    if(pkt.haslayer(ARP)):
      print pkt.src
    if pkt.haslayer(Dot11):
      sig_str = -(256-ord(pkt.notdecoded[-4:-3]))
      mac_addr=""
      ssid=""
      try:
        mac_addr=pkt.addr2
        ssid=pkt.info
      except:
        return
      if self.device_dict.has_key(pkt.addr2) and pkt.info!=self.device_dict[pkt.addr2]:
        output= "DIS MAC:%s RSSI:%s " %(pkt.addr2,sig_str)
        print output
        self.device_dict.pop(pkt.addr2)
        self.not_an_ap[pkt.addr2]=pkt.info
        self.queue.put(output)
      elif pkt.info=="" or pkt.info=="Broadcast":
        output= "DIS MAC:%s RSSI:%s " %(pkt.addr2,sig_str)
        print output
        self.queue.put(output)
      else:
        pot_mac=self.not_an_ap.get(pkt.addr2)
        if pot_mac == None:
          self.device_dict[pkt.addr2]=pkt.info

我不太明白为什么在这个情况下,方法的排列顺序会有影响。

撰写回答