kittyhawk
kittyhawk

Reputation: 698

Python/Scapy Performance on embedded device using Wi-Fi

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?

Upvotes: 2

Views: 2667

Answers (2)

user2722968
user2722968

Reputation: 16475

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.

Upvotes: 2

RyPeck
RyPeck

Reputation: 8147

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.

Upvotes: 3

Related Questions