1

I've got a strange issue with the Scapy sniff() function.

This is how my class is looking:

    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)

This code doesn't work when I call it from my Thread manager class:

EDIT: When I say it doesn't work, I mean that the sniff is either not operational or isn't calling PacketHandler. No error messages are outputted, and the rest of the program continues as normal

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'

I included the sleep function after looking at this post: Scapy fails to sniff

However, when I move my sniff call to the __init__() function, it works, but then no subsequent threads can be called due to the packet_sniffer class being infinitely stuck in the __init__() function.

I'm fairly new programmer when it comes to python (not a new programmer overall, i have lots of experience), so I'm probably doing something really basic wrong.

TIA

James.

Community
  • 1
  • 1
James
  • 349
  • 1
  • 6
  • 17
  • What do you mean by "doesn't work"? – dano Jul 09 '14 at 16:15
  • @dano I'll clarify. When I say it doesn't work, I mean that the sniff is either not operational or isn't calling PacketHandler. No error messages are outputted, and the rest of the program continues as normal. – James Jul 09 '14 at 16:34
  • 1
    Can you verify that `run` is being called? (Just throw a `print` statement in there). Put a print at the top of `PacketHandler`, too. You should be able to figure out where things are either getting stuck or failing just by using `print` to trace the flow. – dano Jul 09 '14 at 16:38
  • I always use print statements, but i didn't think to use the print in the run method as the other classes have the same structure and their run methods work fine. In the packet sniffer class, neither the packet handler or the run method are being called, but the init method works as expected. Any suggestions @dano – James Jul 09 '14 at 16:57

1 Answers1

2

It seems that simply rearranging the class so that the run method came just under the __init__() method fixed the issue. I also stopped using the thread class and used the multiprocess class, which builds on the Thread class but allows greater concurrency.

The final class looks like this:

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

I'm not entirely sure why the arrangement of the methods makes a difference in this instance.

James
  • 349
  • 1
  • 6
  • 17