使用 Scapy 从 Mac OSX 上的数据包获取信号强度
obtain signal strength from packets on Mac OSX with Scapy
背景
我正在尝试从接收到的数据包中获取 RSSI。我知道它们在 Radiotap headers 中可用,但不幸的是我无法嗅探到任何包含 Radiotap headers 的数据包。
我确实找到了 parsePacket method from scapy-rssi,它似乎只过滤掉包含 Radiotap headers 和 RSSI 的数据包(如果我没记错的话)。
我在以下代码中使用了该方法:
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
不幸的是,函数没有输出任何东西——因此没有包包含 Radiotap headers。我尝试使用 sniff("en1mon", prn=packetCallback)
激活监控模式,但没有任何进展。
主要问题:
我还发现,某处MacOSX的en1接口无法访问Dot11headers,是真的吗?如果是这样,那么我如何从 OSX 上的数据包中获取 RSSI 值?
谢谢!
几件事:
- 不要用scapy-rssi,现在基本不需要
- 使用最新开发版本的scapy:https://github.com/secdev/scapy/archive/master.zip(改进了对RSSI的支持,尚未发布)
然后您可能想直接使用 packet[Radiotap].dBm_AntSignal
,如果不是 None,这将是一个负值,而不是整个 parsePacket 东西。
最后,在 OSX 上,您可能需要使用 sniff([...], monitor=True)
以确保正确接收原始数据包
背景
我正在尝试从接收到的数据包中获取 RSSI。我知道它们在 Radiotap headers 中可用,但不幸的是我无法嗅探到任何包含 Radiotap headers 的数据包。
我确实找到了 parsePacket method from scapy-rssi,它似乎只过滤掉包含 Radiotap headers 和 RSSI 的数据包(如果我没记错的话)。
我在以下代码中使用了该方法:
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
不幸的是,函数没有输出任何东西——因此没有包包含 Radiotap headers。我尝试使用 sniff("en1mon", prn=packetCallback)
激活监控模式,但没有任何进展。
主要问题:
我还发现,某处MacOSX的en1接口无法访问Dot11headers,是真的吗?如果是这样,那么我如何从 OSX 上的数据包中获取 RSSI 值?
谢谢!
几件事:
- 不要用scapy-rssi,现在基本不需要
- 使用最新开发版本的scapy:https://github.com/secdev/scapy/archive/master.zip(改进了对RSSI的支持,尚未发布)
然后您可能想直接使用 packet[Radiotap].dBm_AntSignal
,如果不是 None,这将是一个负值,而不是整个 parsePacket 东西。
最后,在 OSX 上,您可能需要使用 sniff([...], monitor=True)
以确保正确接收原始数据包