Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/ppi.py: 78%

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

32 statements  

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> 

5 

6# scapy.contrib.description = CACE Per-Packet Information (PPI) header 

7# scapy.contrib.status = loads 

8 

9""" 

10CACE Per-Packet Information (PPI) header. 

11 

12A method for adding metadata to link-layer packets. 

13 

14For example, one can tag an 802.11 packet with GPS coordinates of where it 

15was captured, and include it in the PCAP file. 

16 

17New PPI types should: 

18 

19 * Make their packet a subclass of ``PPI_Element`` 

20 * Call ``bind_layers(PPI_Hdr, ExamplePPI, pfh_type=0xffff)`` 

21 

22See ``layers/contrib/ppi_cace.py`` for an example. 

23""" 

24 

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 

31 

32 

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 ] 

39 

40 def mysummary(self): 

41 return self.sprintf('PPI %pfh_type%') 

42 

43 

44class PPI_Element(Packet): 

45 """Superclass for all PPI types.""" 

46 name = 'PPI Element' 

47 

48 def extract_padding(self, s): 

49 return b'', s 

50 

51 @staticmethod 

52 def length_from(pkt): 

53 if not pkt.underlayer: 

54 warning('Missing under-layer') 

55 return 0 

56 

57 return pkt.underlayer.len 

58 

59 

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 ] 

71 

72 def add_payload(self, payload): 

73 Packet.add_payload(self, payload) 

74 

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__)) 

78 

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)) 

83 

84 

85conf.l2types.register(DLT_PPI, PPI)