15

How do I check for the presence of a particular layer in a scapy packet? For example, I need to check the src/dst fields of an IP header, how do I know that a particular packet actually has an IP header (as opposed to IPv6 for instance).

My problem is that when I go to check for an IP header field, I get an error saying that the IP layer doesn't exist. Instead of an IP header, this particular packet had IPv6.

pkt = Ether(packet_string)
if pkt[IP].dst == something:
  # do this

My error occurs when I try to reference the IP layer. How do I check for that layers existence before attempting to manipulate it?

Thanks!

Mr. Shickadance
  • 5,283
  • 9
  • 45
  • 61
  • 1
    So what if an exception is thrown? Just catch it and recast it to what you now know it is. – Santa Apr 04 '11 at 15:18
  • While that works, is that something you'd normally want to do? I mean using exceptions to handle cases that aren't really 'exceptional'. Of course, that is a question on its own. I am going to leave this open for a while to see if there is an actual scapy solution. Thanks though! – Mr. Shickadance Apr 04 '11 at 15:34
  • 1
    It's quite Pythonic. The moniker is, "it is better to ask forgiveness than permission." The Python library itself (and its C counterpart) uses the same exception-handling-as-control-structure idiom. – Santa Apr 04 '11 at 15:59
  • Well, sounds good to me. I am new to Python so I hadn't had much exposure to this. At least adding the code in was simple, as are many things in Python. At any rate, I am still going to wait for responses specific to scapy, but I appreciate the insight. – Mr. Shickadance Apr 04 '11 at 17:33

2 Answers2

24

You should try the in operator. It returns True or False depending if the layer is present or not in the Packet.

root@u1010:~/scapy# scapy
Welcome to Scapy (2.2.0-dev)
>>> load_contrib("ospf")
>>> pkts=rdpcap("rogue_ospf_hello.pcap")
>>> p=pkts[0]
>>> IP in p
True
>>> UDP in p
False
>>>
root@u1010:~/scapy#
phoenix
  • 7,988
  • 6
  • 39
  • 45
jliendo
  • 390
  • 6
  • 7
  • That is exactly what I was looking for. I really appreciate Santa's insight as well, because that worked just fine. However I knew there must have been some way of checking this. Thanks to you both! – Mr. Shickadance Apr 05 '11 at 12:59
  • i got error : ```IndexError: Layer [Radius] not found``` while try to import Radius layer, how fix it? – Morteza Soltanabadiyan Oct 15 '20 at 06:54
18

For completion I thought I would also mention the haslayer method.

>>> pkts=rdpcap("rogue_ospf_hello.pcap") 
>>> p=pkts[0]
>>> p.haslayer(UDP)
0
>>> p.haslayer(IP)
1

Hope that helps as well.

phoenix
  • 7,988
  • 6
  • 39
  • 45
dc5553
  • 1,243
  • 11
  • 21
  • 1
    Yeah, this is also what is suggested in Scapy's documentation. – Ricky Robinson Feb 13 '13 at 11:16
  • 2
    [Latest Scapy socs say that `haslayer` is superceded by `cls in self` method](https://scapy.readthedocs.io/en/latest/api/scapy.packet.html?highlight=haslayer#scapy.packet.Packet.haslayer). – phoenix Sep 20 '19 at 13:43