12

I want to know how can I verify that a packet I received from the sr1() function in Scapy contains a TCP layer, in order to do some treatment on the TCP flags.

RyPeck
  • 7,830
  • 3
  • 38
  • 58
farfalla
  • 173
  • 1
  • 1
  • 10

2 Answers2

13

You have two options, the in operator is one.

>>> TCP in pkt
True
>>> if TCP in pkt:
...     # Handle TCP Flags

Packet objects in Scapy also have a function called haslayer().

>>> pkt = IP()/TCP()
>>> pkt.haslayer(TCP)
1
>>> pkt2 = IP()/UDP()
>>> pkt2.haslayer(TCP)
0
>>> Packet.haslayer.__doc__
'true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax.'
RyPeck
  • 7,830
  • 3
  • 38
  • 58
  • Thank you very much RyPeck for your answer, the problem is that the packet I am going to check is the result of an sr1() command in Scapy so these options didn't work for me unfortunately. I got this error message : AttributeError: 'NoneType' object has no attribute 'haslayer' – farfalla Mar 01 '14 at 15:44
  • Sounds like that's because you aren't actually getting a packet back from `sr1`. – RyPeck Mar 01 '14 at 17:26
-1

The accepted answer can match the protocol at unexpected place. In a robust code you should check the protocol at a particular place in the stack of protocols using the method layers():

>>> pkt1 = IP()/TCP()
>>> pkt1.layers()
[scapy.layers.inet.IP, scapy.layers.inet.TCP]
>>> pkt1.layers()[1] == TCP
True
>>> pkt2 = IP()/UDP()
>>> pkt2.layers()[1] == TCP
False

The answer by RyPeck will give incorrect results when the communication is encapsulated. For example here is IP encapsulated in IP:

>>> pkt3 = IP()/IP()/TCP()
>>> pkt3.haslayer(TCP)
True
# We got True although the protocol sent over IP is IP, not TCP.

>>> pkt3.layers()[1] == TCP
False
# Using layers() and the position we want to examine [1] we get the correct result.