secdev / scapy

Scapy: the Python-based interactive packet manipulation program & library.
https://scapy.net
GNU General Public License v2.0
10.67k stars 2.02k forks source link

False negative using packet.haslayer() #1854

Closed willbelr closed 5 years ago

willbelr commented 5 years ago

It seems that haslayer() is broken in scapy 2.4.2-1. An app that used to work fine this summer is now broken, as the method always return 0.

# Details

Python version: 3.7.2-3 Scapy version: 2.4.2-1 OS: Arch Linux (up to date) Package: python-scapy Network adapter: Alfa AWUS036NHA

# Steps to reproduce:

  1. airmon-ng start wlp0s20u2
  2. Run this script:
#!/usr/bin/python3
import scapy.all as scapy
dev = "wlp0s20u2mon"

def parse(packet):
    print("PACKET:", packet.layers())
    print("HAS DOT11:", packet.haslayer(scapy.Dot11))

while True:
    scapy.sniff(iface=dev, prn=parse, count=1, store=False)

Output:

PACKET: [<class 'scapy.layers.dot11.RadioTap'>, <class 'scapy.layers.dot11.Dot11FCS'>, <class 'scapy.layers.dot11.Dot11Beacon'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11EltRates'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11EltRSN'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11Elt'>, <class 'scapy.layers.dot11.Dot11EltVendorSpecific'>, <class 'scapy.layers.dot11.Dot11EltVendorSpecific'>, <class 'scapy.layers.dot11.Dot11EltVendorSpecific'>] HAS DOT11: 0

gpotter2 commented 5 years ago

Hi ! Please retry against master, that was fixed in https://github.com/secdev/scapy/pull/1667

FTR We had introduced native FCS handling, but that lead to some trouble as packets could either be Dot11 or Dot11FCS. It is now fixed, as Dot11 will work for both

haim0n commented 4 years ago

Not sure I'm barking at a right tree, but now it seems that the only way to test whether Dot11 is in the packet is by only accessing it, all other methods fail:

>>> pkt = Dot11FCS()/IP()
>>> Dot11 in pkt
False
>>> pkt.haslayer(Dot11)
0
>>> pkt[Dot11]
<Dot11FCS  |>

And it takes now a try/except wrapping around the code to handle the IndexError in case the pkt doesn't have the layer.

gpotter2 commented 4 years ago

@haim0n Please open a new issue

haim0n commented 4 years ago

Maybe it's worth reopening the original issue?