2

I am using Scapy to capture Wi-Fi client request frames. I am only interested in the MAC and requested SSID address of the clients. I do something like the following.

sniff(iface="mon0", prn=Handler)

def Handler(pkt):
    if pkt.hasLayer(Dot11):
       if pkt.type == 0 and pkt.subtype == 4:
           print pkt.addr2 + " " + pkt.info

My issue is that I am doing this on a embedded device with limited processing power. When I run my script, my processor utilization rises to nearly 100%. I assume this is because of the sheer volume of frames that Scapy is sniffing and passing to my Python code. I also assume that if I could employ the right filter in my sniff command, I could eliminate many of the frames that are not being used and thus reduce the processor load.

Is there a filter statement that could be used to do this?

RyPeck
  • 7,830
  • 3
  • 38
  • 58
kittyhawk
  • 688
  • 2
  • 11
  • 25
  • Could you describe what you have set up on the interface and what type of environment you are operating in? – RyPeck Aug 30 '13 at 17:03

2 Answers2

3

With Scapy it is possible to sniff with an BPF Filter applied to the capture. This will filter out packets at a much lower level then your Handler function is doing, and should significantly improve performance.

There is a simple example in the Scapy documentation.

# Could also add a subtype to this.
sniff(iface="mon0", prn=Handler, filter="type mgt")

Filter pieced together from here specifically.

Unfortunately I can't test this right now, but this information should provide you with a stepping stone to your ultimate solution, or someone else to post exactly what you need. I believe you will also need to set the interface to monitor mode.

You may also find this question of interest - Accessing 802.11 Wireless Management Frames from Python.

Community
  • 1
  • 1
RyPeck
  • 7,830
  • 3
  • 38
  • 58
  • This option might work if I could get the filter to work. Your example throws a Scapy exception of "Filter parse error". – kittyhawk Aug 30 '13 at 18:25
2

Scapy is extremely slow due to the way it decodes the data. You may

  • Use a BPF-filter on the input to only get the frames you are looking for before handing them to scapy. See this module for example. The module uses libpcap to get the data from the air or from a file first and passes it through a dynamically updated BPF-filter to keep unwanted traffic out
  • Write your own parser for wifi in c (which is not too hard, given the limited amount of information you need, there are things like prismhead though)
  • Use tshark from wireshark as a subprocess and collect data from there

I highly recommend the third approach although wiresharek comes with a >120mb library that your embedded device might not be able to handle.

user2722968
  • 13,636
  • 2
  • 46
  • 67