Scapy - retrieving RSSI from WiFi packets

18,442

Solution 1

To summarize:

  • signal strength was not visible because something was wrong in the way that 'monitor mode' was set (not all headers were passed/parsed by sniffers). This monitor interface was created by hostapd.

  • now I'm setting monitor mode on interface with airmon-ng - tcpdump, scapy show theese extra headers.

Edited: use scapy 2.4.1+ (or github dev version). Most recent versions now correctly decode the « notdecoded » part

Solution 2

Here is a valuable scapy extension that improves scapy.layers.dot11.Packet's parsing of present not decoded fields.

https://github.com/ivanlei/airodump-iv/blob/master/airoiv/scapy_ex.py

Just use:

import scapy_ex

And:

packet.show()

It'll look like this:

###[ 802.11 RadioTap ]###
  version   = 0
  pad       = 0
  RadioTap_len= 18
  present   = Flags+Rate+Channel+dBm_AntSignal+Antenna+b14
  Flags     = 0
  Rate      = 2
  Channel   = 1
  Channel_flags= 160
  dBm_AntSignal= -87
  Antenna   = 1
  RX_Flags  = 0

Solution 3

For some reason the packet structure has changed. Now dBm_AntSignal is the first element in notdecoded.

I am not 100% sure of this solution but I used sig_str = -(256 - ord(packet.notdecoded[-2:-1])) to reach first element and I get values that seems to be dBm_AntSignal.

I am using OpenWRT in a TP-Link MR3020 with extroot and Edward Keeble Passive Wifi Monitoring project with some modifications.

I use scapy_ex.py and I had this information:

802.11 RadioTap

  version   = 0

  pad       = 0

  RadioTap_len= 36

  present   = dBm_AntSignal+Lock_Quality+b22+b24+b25+b26+b27+b29

  dBm_AntSignal= 32

  Lock_Quality= 8

Solution 4

If someone still has the same issue, I think I have found the solution:

I believe this is the right cut for the RSSI value:

sig_str = -(256-ord(packet.notdecoded[-3:-2]))

and this one is for the noise level:

noise_str = -(256-ord(packet.notdecoded[-2:-1]))
Share:
18,442

Related videos on Youtube

kaczor1984
Author by

kaczor1984

Updated on June 04, 2022

Comments

  • kaczor1984
    kaczor1984 almost 2 years

    I'm trying to get RSSI or signal strength from WiFi packets. I want also RSSI from 'WiFi probe requests' (when somebody is searching for a WiFi hotspots).

    I managed to see it from kismet logs but that was only to make sure it is possible - I don't want to use kismet all the time.

    For 'full time scanning' I'm using scapy. Does anybody know where can I find the RSSI or signal strength (in dBm) from the packets sniffed with scapy? I don't know how is the whole packet built - and there are a lot of 'hex' values which I don't know how to parse/interpret.

    I'm sniffing on both interfaces - wlan0 (detecting when somebody connects to my hotspot), and mon.wlan0 (detecting when somebody is searching for hotspots). Hardware (WiFi card) I use is based on Prism chipset (ISL3886). However test with Kismet was ran on Atheros (AR2413) and Intel iwl4965.

    Edit1:

    Looks like I need to access somehow information stored in PrismHeader: http://trac.secdev.org/scapy/browser/scapy/layers/dot11.py line 92 ?

    Anybody knows how to enter this information? packet.show() and packet.show2() don't show anything from this Class/Layer

    Edit2:

    After more digging it appears that the interface just isn't set correctly and that's why it doesn't collect all necessary headers. If I run kismet and then sniff packets from that interface with scapy there is more info in the packet:

    ###[ RadioTap dummy ]###
      version= 0
      pad= 0
      len= 26
      present= TSFT+Flags+Rate+Channel+dBm_AntSignal+Antenna+b14
      notdecoded= '8`/\x08\x00\x00\x00\x00\x10\x02\x94\t\xa0\x00\xdb\x01\x00\x00'
      ...
    

    Now I only need to set the interface correctly without using kismet.

    • Cukic0d
      Cukic0d almost 6 years
      Now decided in scapy 2.4.1+ or the github version
  • kaczor1984
    kaczor1984 about 11 years
    Yes I was. It's 'hidden' in the notdecoded part of the packet. I'm extracting it with: sig_str = -(256-ord(packet.notdecoded[-4:-3]))
  • zengr
    zengr almost 11 years
    @kaczor1984 I tried: sig_str = -(256-ord(packet.notdecoded[-4:-3])) and I get values like -69, -79, -81 etc. How do you interpret these values?
  • kaczor1984
    kaczor1984 almost 11 years
    Just like you see them. RSSI between -100 and 0 where 0 means that device was exactly at the place of 'detector' and -100 means very far away. Of course I don't get usually values higher than ~-30.
  • Pierz
    Pierz almost 9 years
    You're best to clone the git repo and run the import scapy_ex from the airoiv directory as there other dependent files required by just scapy_ex.py (e.g. printer.py). Then it works nicely.
  • Cukic0d
    Cukic0d almost 6 years
    This may work on your machine, but isn’t a universal fix. Notdecoded is full of all tags added by your driver, meaning that you should check which flags are present. ([-4:-3] will not be the same on every computer). In most recent version of scapy (2.4.1+ or the github dev version, it is now properly decoded)
  • Cukic0d
    Cukic0d almost 6 years
    Not requires anymore as merged into the main repo
  • Shameer Kashif
    Shameer Kashif almost 6 years
    It's not. Every computer displays different information depending on the driver, the interface is using...
  • Shameer Kashif
    Shameer Kashif almost 6 years
    Doing this completely messed up the Dot11Beacon frame structure. Some tests like pkt.haslayer are no longer useful.