Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scapy/layers/ppi.py: 77%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: GPL-2.0-or-later
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Original PPI author: <jellch@harris.com>
6# scapy.contrib.description = CACE Per-Packet Information (PPI) header
7# scapy.contrib.status = loads
9"""
10CACE Per-Packet Information (PPI) header.
12A method for adding metadata to link-layer packets.
14For example, one can tag an 802.11 packet with GPS coordinates of where it
15was captured, and include it in the PCAP file.
17New PPI types should:
19 * Make their packet a subclass of ``PPI_Element``
20 * Call ``bind_layers(PPI_Hdr, ExamplePPI, pfh_type=0xffff)``
22See ``layers/contrib/ppi_cace.py`` for an example.
23"""
25from scapy.config import conf
26from scapy.data import DLT_PPI, PPI_TYPES
27from scapy.error import warning
28from scapy.packet import Packet
29from scapy.fields import ByteField, FieldLenField, LEIntField, \
30 PacketListField, LEShortEnumField, LenField
33class PPI_Hdr(Packet):
34 name = 'PPI Header'
35 fields_desc = [
36 LEShortEnumField('pfh_type', 0, PPI_TYPES),
37 LenField('pfh_length', None, fmt='<H'),
38 ]
40 def mysummary(self):
41 return self.sprintf('PPI %pfh_type%')
44class PPI_Element(Packet):
45 """Superclass for all PPI types."""
46 name = 'PPI Element'
48 def extract_padding(self, s):
49 return b'', s
51 @staticmethod
52 def length_from(pkt):
53 if not pkt.underlayer:
54 warning('Missing under-layer')
55 return 0
57 return pkt.underlayer.len
60class PPI(Packet):
61 name = 'Per-Packet Information header (PPI)'
62 fields_desc = [
63 ByteField('version', 0),
64 ByteField('flags', 0),
65 FieldLenField('len', None, length_of='headers', fmt='<H',
66 adjust=lambda p, x: x + 8), # length of this packet
67 LEIntField('dlt', None),
68 PacketListField('headers', [], PPI_Hdr,
69 length_from=lambda p: p.len - 8),
70 ]
72 def add_payload(self, payload):
73 Packet.add_payload(self, payload)
75 # Update the DLT if not set
76 if self.getfieldval('dlt') is None and isinstance(payload, Packet):
77 self.setfieldval('dlt', conf.l2types.get(payload.__class__))
79 def guess_payload_class(self, payload):
80 # Pass DLT handling to conf.l2types.
81 return conf.l2types.get(
82 self.getfieldval('dlt'), Packet.guess_payload_class(self, payload))
85conf.l2types.register(DLT_PPI, PPI)