Search code examples
macoswifiscapyrssi

obtain signal strength from packets on Mac OSX with Scapy


Background

I'm trying to acquire RSSI from received packets. I know they are available in Radiotap headers, but unfortunately I wasn't able to sniff any packet containing Radiotap headers in it.

I did find parsePacket method from scapy-rssi, which seems to only filter out packets containing Radiotap headers with RSSI (If I'm not mistaken).

I've utilized that method in the following code:

def parsePacket(pkt):
  if pkt.haslayer(scapy.all.Dot11):
    if pkt.addr2 is not None:
      # check available Radiotap fields
      field, val = pkt.getfield_and_val("present")
      names = [field.names[i][0] for i in range(len(field.names)) if (1 << i) & val != 0]
      # check if we measured signal strength
      if "dBm_AntSignal" in names:
        # decode radiotap header
        fmt = "<"
        rssipos = 0
        for name in names:
          # some fields consist of more than one value
          if name == "dBm_AntSignal":
            # correct for little endian format sign
            rssipos = len(fmt)-1
          fmt = fmt + self.radiotap_formats[name]
        # unfortunately not all platforms work equally well and on my arm
        # platform notdecoded was padded with a ton of zeros without
        # indicating more fields in pkt.len and/or padding in pkt.pad
        decoded = struct.unpack(fmt, pkt.notdecoded[:struct.calcsize(fmt)])
        return pkt.addr2, decoded[rssipos]

def packetCallback(pkt):
  parsed = parsePacket(pkt)
  if parsed:
    print(parsed)

sniff("en1", prn=packetCallback)  #en1 is a wlan interface on my OSX

Unfortunately function was not outputting anything - therefore no packets contained Radiotap headers. I tried activating an monitor mode with sniff("en1mon", prn=packetCallback), but there was no progress.


Main Problem:

I also found, somewhere that en1 interface of Mac OSX does not have access to Dot11 headers, is that true? If that's the case, then how can I get RSSI value from packets on OSX?

Thank you!


Solution

  • Several things:

    You may then want to use packet[Radiotap].dBm_AntSignal directly, which will be a negative value when not None, instead of the whole parsePacket thing.

    Lastly, on OSX you might need to use sniff([...], monitor=True) to be sure to properly receive the raw packets