pypcapkit 1.3.1.post6__cp311-none-any.whl → 1.3.5.post6__cp311-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. pcapkit/__init__.py +1 -3
  2. pcapkit/__main__.py +2 -2
  3. pcapkit/const/ftp/command.py +2 -2
  4. pcapkit/const/ftp/return_code.py +11 -21
  5. pcapkit/const/http/status_code.py +7 -3
  6. pcapkit/const/ipv6/extension_header.py +3 -0
  7. pcapkit/const/ipv6/router_alert.py +1 -1
  8. pcapkit/const/ipv6/routing.py +2 -4
  9. pcapkit/const/ipx/packet.py +3 -0
  10. pcapkit/const/ipx/socket.py +2 -2
  11. pcapkit/const/mh/status_code.py +1 -1
  12. pcapkit/const/reg/apptype.py +104 -33
  13. pcapkit/const/reg/ethertype.py +8 -10
  14. pcapkit/const/reg/linktype.py +48 -81
  15. pcapkit/const/reg/transtype.py +9 -3
  16. pcapkit/const/tcp/option.py +2 -2
  17. pcapkit/corekit/infoclass.py +2 -0
  18. pcapkit/dumpkit/pcap.py +13 -5
  19. pcapkit/protocols/data/application/ftp.py +2 -2
  20. pcapkit/protocols/data/application/httpv1.py +2 -1
  21. pcapkit/protocols/data/application/httpv2.py +2 -1
  22. pcapkit/protocols/data/internet/ah.py +2 -2
  23. pcapkit/protocols/data/internet/hip.py +2 -1
  24. pcapkit/protocols/data/internet/hopopt.py +2 -1
  25. pcapkit/protocols/data/internet/ipv4.py +2 -1
  26. pcapkit/protocols/data/internet/ipv6.py +2 -2
  27. pcapkit/protocols/data/internet/ipv6_frag.py +2 -2
  28. pcapkit/protocols/data/internet/ipv6_opts.py +2 -1
  29. pcapkit/protocols/data/internet/ipv6_route.py +2 -2
  30. pcapkit/protocols/data/internet/ipx.py +2 -1
  31. pcapkit/protocols/data/internet/mh.py +2 -1
  32. pcapkit/protocols/data/link/arp.py +2 -1
  33. pcapkit/protocols/data/link/ethernet.py +2 -1
  34. pcapkit/protocols/data/link/l2tp.py +4 -2
  35. pcapkit/protocols/data/link/ospf.py +4 -2
  36. pcapkit/protocols/data/link/vlan.py +2 -1
  37. pcapkit/protocols/data/misc/null.py +2 -2
  38. pcapkit/protocols/data/misc/pcap/frame.py +4 -2
  39. pcapkit/protocols/data/misc/pcap/header.py +2 -1
  40. pcapkit/protocols/data/misc/pcapng.py +16 -8
  41. pcapkit/protocols/data/misc/raw.py +3 -5
  42. pcapkit/protocols/data/protocol.py +8 -0
  43. pcapkit/protocols/data/transport/tcp.py +6 -3
  44. pcapkit/protocols/data/transport/udp.py +2 -2
  45. pcapkit/protocols/internet/internet.py +15 -6
  46. pcapkit/protocols/internet/ipv6.py +54 -3
  47. pcapkit/protocols/internet/ipv6_route.py +5 -7
  48. pcapkit/protocols/link/link.py +1 -1
  49. pcapkit/protocols/misc/pcap/frame.py +1 -1
  50. pcapkit/protocols/misc/pcapng.py +5 -2
  51. pcapkit/protocols/misc/raw.py +0 -1
  52. pcapkit/protocols/protocol.py +4 -1
  53. pcapkit/protocols/schema/__init__.py +0 -1
  54. pcapkit/protocols/schema/internet/ipv6_route.py +2 -3
  55. pcapkit/protocols/schema/schema.py +1 -1
  56. pcapkit/protocols/transport/tcp.py +1 -1
  57. pcapkit/protocols/transport/udp.py +1 -1
  58. pcapkit/toolkit/pcapng.py +1 -1
  59. pcapkit/utilities/decorators.py +4 -2
  60. pcapkit/utilities/exceptions.py +5 -5
  61. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/METADATA +33 -31
  62. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/RECORD +66 -66
  63. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/WHEEL +1 -1
  64. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/LICENSE +0 -0
  65. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/entry_points.txt +0 -0
  66. {pypcapkit-1.3.1.post6.dist-info → pypcapkit-1.3.5.post6.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from ipaddress import IPv4Address, IPv6Address
@@ -43,7 +44,7 @@ class Type(Data):
43
44
 
44
45
 
45
46
  @info_final
46
- class ARP(Data):
47
+ class ARP(Protocol):
47
48
  """Data model for ARP packet."""
48
49
 
49
50
  #: Hardware type.
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from pcapkit.const.reg.ethertype import EtherType
@@ -13,7 +14,7 @@ __all__ = ['Ethernet']
13
14
 
14
15
 
15
16
  @info_final
16
- class Ethernet(Data):
17
+ class Ethernet(Protocol):
17
18
  """Data model for ethernet packet."""
18
19
 
19
20
  #: Destination MAC address.
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from typing import Optional
@@ -34,7 +35,7 @@ class Flags(Data):
34
35
 
35
36
 
36
37
  @info_final
37
- class L2TP(Data):
38
+ class L2TP(Protocol):
38
39
  """Data model for L2TP packet."""
39
40
 
40
41
  #: Flags and version info.
@@ -58,4 +59,5 @@ class L2TP(Data):
58
59
  #: Header length.
59
60
  hdr_len: 'int'
60
61
 
61
- def __init__(self, flags: 'Flags', version: 'int', length: 'Optional[int]', tunnelid: 'int', sessionid: 'int', ns: 'Optional[int]', nr: 'Optional[int]', offset: 'Optional[int]') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,redefined-builtin,multiple-statements,line-too-long
62
+ def __init__(self, flags: 'Flags', version: 'int', length: 'Optional[int]', tunnelid: 'int', sessionid: 'int',
63
+ ns: 'Optional[int]', nr: 'Optional[int]', offset: 'Optional[int]') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,redefined-builtin,multiple-statements,line-too-long
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from ipaddress import IPv4Address
@@ -31,7 +32,7 @@ class CrytographicAuthentication(Data):
31
32
 
32
33
 
33
34
  @info_final
34
- class OSPF(Data):
35
+ class OSPF(Protocol):
35
36
  """Data model for OSPF packet."""
36
37
 
37
38
  #: Version number.
@@ -53,4 +54,5 @@ class OSPF(Data):
53
54
  #: Authentication.
54
55
  auth: 'bytes | CrytographicAuthentication'
55
56
 
56
- def __init__(self, version: 'int', type: 'Packet', len: 'int', router_id: 'IPv4Address', area_id: 'IPv4Address', chksum: 'bytes', autype: 'Authentication') -> 'None': ... # pylint: disable=super-init-not-called,unused-argument,line-too-long,multiple-statements,redefined-builtin
57
+ def __init__(self, version: 'int', type: 'Packet', len: 'int', router_id: 'IPv4Address',
58
+ area_id: 'IPv4Address', chksum: 'bytes', autype: 'Authentication') -> 'None': ... # pylint: disable=super-init-not-called,unused-argument,line-too-long,multiple-statements,redefined-builtin
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from pcapkit.const.reg.ethertype import EtherType
@@ -29,7 +30,7 @@ class TCI(Data):
29
30
 
30
31
 
31
32
  @info_final
32
- class VLAN(Data):
33
+ class VLAN(Protocol):
33
34
  """Data model for 802.1Q customer VLAN tag type."""
34
35
 
35
36
  #: Tag control information.
@@ -2,13 +2,13 @@
2
2
  """data models for no-payload packet"""
3
3
 
4
4
  from pcapkit.corekit.infoclass import info_final
5
- from pcapkit.protocols.data.data import Data
5
+ from pcapkit.protocols.data.protocol import Protocol
6
6
 
7
7
  __all__ = ['NoPayload']
8
8
 
9
9
 
10
10
  @info_final
11
- class NoPayload(Data):
11
+ class NoPayload(Protocol):
12
12
  """No-payload packet is an empty packet."""
13
13
 
14
14
  # NOTE: We add this method for both type annotation and to mark that this
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from datetime import datetime
@@ -31,7 +32,7 @@ class FrameInfo(Data):
31
32
 
32
33
 
33
34
  @info_final
34
- class Frame(Data):
35
+ class Frame(Protocol):
35
36
  """Frame header of PCAP file."""
36
37
 
37
38
  #: Metadata information.
@@ -51,4 +52,5 @@ class Frame(Data):
51
52
  #: Protocol chain.
52
53
  protocols: 'str'
53
54
 
54
- def __init__(self, frame_info: 'FrameInfo', time: 'datetime', number: 'int', time_epoch: 'Decimal', len: 'int', cap_len: 'int') -> 'None': ... # pylint: disable=unused-argument,multiple-statements,super-init-not-called,line-too-long,redefined-builtin
55
+ def __init__(self, frame_info: 'FrameInfo', time: 'datetime', number: 'int', time_epoch: 'Decimal',
56
+ len: 'int', cap_len: 'int') -> 'None': ... # pylint: disable=unused-argument,multiple-statements,super-init-not-called,line-too-long,redefined-builtin
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from typing_extensions import Literal
@@ -31,7 +32,7 @@ class MagicNumber(Data):
31
32
 
32
33
 
33
34
  @info_final
34
- class Header(Data):
35
+ class Header(Protocol):
35
36
  """Global header of PCAP file."""
36
37
 
37
38
  #: Magic number.
@@ -8,6 +8,7 @@ from typing import TYPE_CHECKING
8
8
  from pcapkit.corekit.infoclass import info_final
9
9
  from pcapkit.corekit.multidict import MultiDict
10
10
  from pcapkit.protocols.data.data import Data
11
+ from pcapkit.protocols.data.protocol import Protocol
11
12
  from pcapkit.utilities.compat import localcontext
12
13
 
13
14
  __all__ = [
@@ -59,7 +60,7 @@ if TYPE_CHECKING:
59
60
  WireGuardKeyLabel)
60
61
 
61
62
 
62
- class PCAPNG(Data):
63
+ class PCAPNG(Protocol):
63
64
  """Data model for PCAP-NG file blocks."""
64
65
 
65
66
  #: Block type.
@@ -145,7 +146,8 @@ class SectionHeaderBlock(PCAPNG):
145
146
  options: 'OrderedMultiDict[Enum_OptionType, Option]'
146
147
 
147
148
  if TYPE_CHECKING:
148
- def __init__(self, type: 'Enum_BlockType', length: 'int', byteorder: 'Literal["big", "little"]', version: 'VersionInfo', # pylint: disable=unused-argument
149
+ def __init__(self, type: 'Enum_BlockType', length: 'int', byteorder: 'Literal["big", "little"]',
150
+ version: 'VersionInfo', # pylint: disable=unused-argument
149
151
  section_length: 'int', options: 'OrderedMultiDict[Enum_OptionType, Option]') -> None: ...
150
152
 
151
153
 
@@ -255,7 +257,8 @@ class IF_FilterOption(Option):
255
257
  expression: 'bytes'
256
258
 
257
259
  if TYPE_CHECKING:
258
- def __init__(self, type: 'Enum_OptionType', length: 'int', code: 'Enum_FilterType', expression: 'bytes') -> None: ...
260
+ def __init__(self, type: 'Enum_OptionType', length: 'int', code: 'Enum_FilterType',
261
+ expression: 'bytes') -> None: ...
259
262
 
260
263
 
261
264
  @info_final
@@ -384,7 +387,8 @@ class EPB_HashOption(Option):
384
387
  hash: 'bytes'
385
388
 
386
389
  if TYPE_CHECKING:
387
- def __init__(self, type: 'Enum_OptionType', length: 'int', algorithm: 'Enum_HashAlgorithm', hash: 'bytes') -> 'None': ...
390
+ def __init__(self, type: 'Enum_OptionType', length: 'int', algorithm: 'Enum_HashAlgorithm',
391
+ hash: 'bytes') -> 'None': ...
388
392
 
389
393
 
390
394
  @info_final
@@ -430,7 +434,8 @@ class EPB_VerdictOption(Option):
430
434
  value: 'bytes'
431
435
 
432
436
  if TYPE_CHECKING:
433
- def __init__(self, type: 'Enum_OptionType', length: 'int', verdict: 'Enum_VerdictType', value: 'bytes') -> 'None': ...
437
+ def __init__(self, type: 'Enum_OptionType', length: 'int', verdict: 'Enum_VerdictType',
438
+ value: 'bytes') -> 'None': ...
434
439
 
435
440
 
436
441
  @info_final
@@ -623,7 +628,8 @@ class NameResolutionBlock(PCAPNG):
623
628
  #: Name resolution mapping (name -> IP address).
624
629
  reverse_mapping: 'MultiDict[str, IPv4Address | IPv6Address]'
625
630
 
626
- def __init__(self, type: 'Enum_BlockType', length: 'int', records: 'OrderedMultiDict[Enum_RecordType, NameResolutionRecord]',
631
+ def __init__(self, type: 'Enum_BlockType', length: 'int',
632
+ records: 'OrderedMultiDict[Enum_RecordType, NameResolutionRecord]',
627
633
  options: 'OrderedMultiDict[Enum_OptionType, Option]') -> 'None': ...
628
634
 
629
635
 
@@ -736,7 +742,8 @@ class SystemdJournalExportBlock(PCAPNG):
736
742
  data: 'tuple[OrderedMultiDict[str, str | bytes], ...]'
737
743
 
738
744
  if TYPE_CHECKING:
739
- def __init__(self, type: 'Enum_BlockType', length: 'int', data: 'tuple[OrderedMultiDict[str, str | bytes], ...]') -> 'None': ...
745
+ def __init__(self, type: 'Enum_BlockType', length: 'int',
746
+ data: 'tuple[OrderedMultiDict[str, str | bytes], ...]') -> 'None': ...
740
747
 
741
748
 
742
749
  class DSBSecrets(Data):
@@ -880,7 +887,8 @@ class PACK_HashOption(Option):
880
887
  hash: 'bytes'
881
888
 
882
889
  if TYPE_CHECKING:
883
- def __init__(self, type: 'Enum_OptionType', length: 'int', algorithm: 'Enum_HashAlgorithm', hash: 'bytes') -> 'None': ...
890
+ def __init__(self, type: 'Enum_OptionType', length: 'int', algorithm: 'Enum_HashAlgorithm',
891
+ hash: 'bytes') -> 'None': ...
884
892
 
885
893
 
886
894
  @info_final
@@ -4,7 +4,7 @@
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
- from pcapkit.protocols.data.data import Data
7
+ from pcapkit.protocols.data.protocol import Protocol
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from typing import Optional
@@ -13,15 +13,13 @@ __all__ = ['Raw']
13
13
 
14
14
 
15
15
  @info_final
16
- class Raw(Data):
16
+ class Raw(Protocol):
17
17
  """Raw packet is an unknown protocol."""
18
18
 
19
19
  #: Original enumeration of this protocol.
20
20
  protocol: 'Optional[int]'
21
- #: packet data
22
- packet: 'bytes'
23
21
  #: error instance when parsing packet data
24
22
  error: 'Optional[Exception]'
25
23
 
26
24
  if TYPE_CHECKING:
27
- def __init__(self, protocol: 'Optional[int]', packet: 'bytes', error: 'Optional[Exception]') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements
25
+ def __init__(self, protocol: 'Optional[int]', error: 'Optional[Exception]') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements
@@ -11,6 +11,14 @@ __all__ = [
11
11
  ]
12
12
 
13
13
 
14
+ class Protocol(Data):
15
+ """Root protocol."""
16
+
17
+ if TYPE_CHECKING:
18
+ #: Packet payload.
19
+ packet: 'bytes'
20
+
21
+
14
22
  @info_final
15
23
  class Packet(Data):
16
24
  """Header and payload data."""
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
7
  from pcapkit.protocols.data.data import Data
8
+ from pcapkit.protocols.data.protocol import Protocol
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from datetime import timedelta
@@ -67,11 +68,12 @@ class Flags(Data):
67
68
  fin: 'bool'
68
69
 
69
70
  if TYPE_CHECKING:
70
- def __init__(self, cwr: 'bool', ece: 'bool', urg: 'bool', ack: 'bool', psh: 'bool', rst: 'bool', syn: 'bool', fin: 'bool') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements,line-too-long,redefined-builtin
71
+ def __init__(self, cwr: 'bool', ece: 'bool', urg: 'bool', ack: 'bool',
72
+ psh: 'bool', rst: 'bool', syn: 'bool', fin: 'bool') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements,line-too-long,redefined-builtin
71
73
 
72
74
 
73
75
  @info_final
74
- class TCP(Data):
76
+ class TCP(Protocol):
75
77
  """Data model for TCP packet."""
76
78
 
77
79
  #: Source port.
@@ -99,7 +101,8 @@ class TCP(Data):
99
101
  #: Connection control flags.
100
102
  connection: 'TCP_Flags'
101
103
 
102
- def __init__(self, srcport: 'AppType', dstport: 'AppType', seq: 'int', ack: 'int', hdr_len: 'int', flags: 'Flags', window_size: 'int', checksum: 'bytes', urgent_pointer: 'int') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements,line-too-long,redefined-builtin
104
+ def __init__(self, srcport: 'AppType', dstport: 'AppType', seq: 'int', ack: 'int', hdr_len: 'int',
105
+ flags: 'Flags', window_size: 'int', checksum: 'bytes', urgent_pointer: 'int') -> 'None': ... # pylint: disable=unused-argument,super-init-not-called,multiple-statements,line-too-long,redefined-builtin
103
106
 
104
107
 
105
108
  class Option(Data):
@@ -4,7 +4,7 @@
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  from pcapkit.corekit.infoclass import info_final
7
- from pcapkit.protocols.data.data import Data
7
+ from pcapkit.protocols.data.protocol import Protocol
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from pcapkit.const.reg.apptype import AppType
@@ -13,7 +13,7 @@ __all__ = ['UDP']
13
13
 
14
14
 
15
15
  @info_final
16
- class UDP(Data):
16
+ class UDP(Protocol):
17
17
  """Data model for UDP protocol."""
18
18
 
19
19
  #: Source port.
@@ -83,7 +83,7 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
83
83
  #: c.f. :meth:`self._decode_next_layer <pcapkit.protocols.internet.internet.Internet._decode_next_layer>`
84
84
  #: & :meth:`self._import_next_layer <pcapkit.protocols.internet.internet.Internet._import_next_layer>`.
85
85
  __proto__ = collections.defaultdict(
86
- lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'), # type: ignore[return-value,arg-type]
86
+ lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
87
87
  {
88
88
  Enum_TransType.HOPOPT: ModuleDescriptor('pcapkit.protocols.internet.hopopt', 'HOPOPT'),
89
89
  Enum_TransType.IPv4: ModuleDescriptor('pcapkit.protocols.internet.ipv4', 'IPv4'),
@@ -157,7 +157,8 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
157
157
 
158
158
  def _decode_next_layer(self, dict_: '_PT', proto: 'Optional[int]' = None, # pylint: disable=arguments-differ
159
159
  length: 'Optional[int]' = None, *, packet: 'Optional[dict[str, Any]]' = None,
160
- version: 'Literal[4, 6]' = 4, ipv6_exthdr: 'Optional[ProtoChain]' = None) -> '_PT':
160
+ version: 'Literal[4, 6]' = 4, ipv6_exthdr: 'Optional[ProtoChain]' = None,
161
+ payload: 'Optional[bytes]' = None) -> '_PT':
161
162
  r"""Decode next layer extractor.
162
163
 
163
164
  Arguments:
@@ -167,6 +168,8 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
167
168
  packet: packet info (passed from :meth:`self.unpack <pcapkit.protocols.protocol.Protocol.unpack>`)
168
169
  version: IP version
169
170
  ipv6_exthdr: protocol chain of IPv6 extension headers
171
+ payload: payload from packet. If not provided, will extract from
172
+ :meth:`self.__header__.get_payload <pcapkit.protocols.schema.schema.Schema.get_payload>`
170
173
 
171
174
  Returns:
172
175
  Current protocol with next layer extracted.
@@ -179,7 +182,8 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
179
182
 
180
183
  """
181
184
  next_ = cast('Protocol', # type: ignore[redundant-cast]
182
- self._import_next_layer(proto, length, packet=packet, version=version)) # type: ignore[arg-type,misc,call-arg]
185
+ self._import_next_layer(proto, length, packet=packet, version=version,
186
+ payload=payload)) # type: ignore[arg-type,misc,call-arg]
183
187
  info, chain = next_.info, next_.protochain
184
188
 
185
189
  # make next layer protocol name
@@ -203,8 +207,8 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
203
207
 
204
208
  @beholder # type: ignore[arg-type]
205
209
  def _import_next_layer(self, proto: 'int', length: 'Optional[int]' = None, *, # pylint: disable=arguments-differ
206
- packet: 'Optional[dict[str, Any]]' = None,
207
- version: 'Literal[4, 6]' = 4, extension: 'bool' = False) -> 'Protocol':
210
+ packet: 'Optional[dict[str, Any]]' = None, version: 'Literal[4, 6]' = 4,
211
+ extension: 'bool' = False, payload: 'Optional[bytes]' = None) -> 'Protocol':
208
212
  """Import next layer extractor.
209
213
 
210
214
  Arguments:
@@ -213,6 +217,8 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
213
217
  packet: packet info (passed from :meth:`self.unpack <pcapkit.protocols.protocol.Protocol.unpack>`)
214
218
  version: IP protocol version
215
219
  extension: if is extension header
220
+ payload: payload from packet. If not provided, will extract from
221
+ :meth:`self.__header__.get_payload <pcapkit.protocols.schema.schema.Schema.get_payload>`
216
222
 
217
223
  Returns:
218
224
  Instance of next layer.
@@ -221,7 +227,10 @@ class Internet(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstra
221
227
  if TYPE_CHECKING:
222
228
  protocol: 'Type[Protocol]'
223
229
 
224
- file_ = self.__header__.get_payload()
230
+ if payload is None:
231
+ file_ = self.__header__.get_payload()
232
+ else:
233
+ file_ = payload
225
234
  if length is None:
226
235
  length = len(file_)
227
236
 
@@ -31,11 +31,13 @@ from typing import TYPE_CHECKING
31
31
 
32
32
  from pcapkit.const.ipv6.extension_header import ExtensionHeader as Enum_ExtensionHeader
33
33
  from pcapkit.const.reg.transtype import TransType as Enum_TransType
34
+ from pcapkit.corekit.module import ModuleDescriptor
34
35
  from pcapkit.corekit.multidict import OrderedMultiDict
35
36
  from pcapkit.corekit.protochain import ProtoChain
36
37
  from pcapkit.protocols.data.internet.ipv6 import IPv6 as Data_IPv6
37
38
  from pcapkit.protocols.internet.ip import IP
38
39
  from pcapkit.protocols.schema.internet.ipv6 import IPv6 as Schema_IPv6
40
+ from pcapkit.utilities.decorators import beholder
39
41
 
40
42
  if TYPE_CHECKING:
41
43
  from enum import IntEnum as StdlibEnum
@@ -46,7 +48,6 @@ if TYPE_CHECKING:
46
48
  from typing_extensions import Literal
47
49
 
48
50
  from pcapkit.protocols.protocol import ProtocolBase as Protocol
49
- from pcapkit.protocols.schema.schema import Schema
50
51
 
51
52
  __all__ = ['IPv6']
52
53
 
@@ -310,6 +311,7 @@ class IPv6(IP[Data_IPv6, Schema_IPv6],
310
311
  _protos = [] # ProtoChain buffer
311
312
 
312
313
  # traverse if next header is an extensive header
314
+ payload = self.__header__.get_payload()
313
315
  while True:
314
316
  try:
315
317
  ex_proto = Enum_ExtensionHeader(proto)
@@ -322,7 +324,8 @@ class IPv6(IP[Data_IPv6, Schema_IPv6],
322
324
  # break
323
325
 
324
326
  # make protocol name
325
- next_ = self._import_next_layer(proto, packet=packet, version=6, extension=True) # type: ignore[misc,call-arg,arg-type]
327
+ next_ = self._import_next_layer(proto, packet=packet, version=6, extension=True,
328
+ payload=payload) # type: ignore[misc,call-arg,arg-type]
326
329
  info = next_.info
327
330
  name = next_.alias.lstrip('IPv6-').lower()
328
331
  ipv6.__update__({
@@ -348,6 +351,9 @@ class IPv6(IP[Data_IPv6, Schema_IPv6],
348
351
  })
349
352
  break
350
353
 
354
+ # update payload for next extension header
355
+ payload = payload[next_.length:]
356
+
351
357
  # record real header & payload length (headers exclude)
352
358
  ipv6.__update__({
353
359
  'hdr_len': hdr_len,
@@ -358,4 +364,49 @@ class IPv6(IP[Data_IPv6, Schema_IPv6],
358
364
  })
359
365
 
360
366
  ipv6_exthdr = ProtoChain.from_list(_protos) # type: ignore[arg-type]
361
- return super()._decode_next_layer(ipv6, proto, raw_len, packet=packet, ipv6_exthdr=ipv6_exthdr)
367
+ return super()._decode_next_layer(ipv6, proto, raw_len, packet=packet, ipv6_exthdr=ipv6_exthdr, payload=payload)
368
+
369
+ @beholder # type: ignore[arg-type]
370
+ def _import_next_layer(self, proto: 'int', length: 'Optional[int]' = None, *, # pylint: disable=arguments-differ
371
+ packet: 'Optional[dict[str, Any]]' = None, version: 'Literal[4, 6]' = 4,
372
+ extension: 'bool' = False, payload: 'Optional[bytes]' = None) -> 'Protocol':
373
+ """Import next layer extractor.
374
+
375
+ Arguments:
376
+ proto: next layer protocol index
377
+ length: valid (*non-padding*) length
378
+ packet: packet info (passed from :meth:`self.unpack <pcapkit.protocols.protocol.Protocol.unpack>`)
379
+ version: IP protocol version
380
+ extension: if is extension header
381
+ payload: payload from packet. If not provided, will extract from
382
+ :meth:`self.__header__.get_payload <pcapkit.protocols.schema.schema.Schema.get_payload>`
383
+
384
+ Returns:
385
+ Instance of next layer.
386
+
387
+ """
388
+ if TYPE_CHECKING:
389
+ protocol: 'Type[Protocol]'
390
+
391
+ if payload is None:
392
+ file_ = self.__header__.get_payload()
393
+ else:
394
+ file_ = payload
395
+ if length is None:
396
+ length = len(file_)
397
+
398
+ if length == 0:
399
+ from pcapkit.protocols.misc.null import \
400
+ NoPayload as protocol # isort: skip # pylint: disable=import-outside-toplevel
401
+ elif self._sigterm:
402
+ from pcapkit.protocols.misc.raw import \
403
+ Raw as protocol # isort: skip # pylint: disable=import-outside-toplevel
404
+ else:
405
+ protocol = self.__proto__[proto] # type: ignore[assignment]
406
+ if isinstance(protocol, ModuleDescriptor):
407
+ protocol = protocol.klass # type: ignore[unreachable]
408
+ self.__proto__[proto] = protocol # update mapping upon import
409
+
410
+ next_ = protocol(file_, length, version=version, extension=extension, # type: ignore[abstract]
411
+ alias=proto, packet=packet, layer=self._exlayer, protocol=self._exproto)
412
+ return next_
@@ -48,14 +48,12 @@ from pcapkit.utilities.warnings import RegistryWarning, warn
48
48
  if TYPE_CHECKING:
49
49
  from enum import IntEnum as StdlibEnum
50
50
  from ipaddress import IPv6Address
51
- from typing import IO, Any, Callable, DefaultDict, NoReturn, Optional, Type
51
+ from typing import IO, Any, Callable, DefaultDict, Optional, Type
52
52
 
53
53
  from aenum import IntEnum as AenumEnum
54
54
  from mypy_extensions import DefaultArg, KwArg, NamedArg
55
55
  from typing_extensions import Literal
56
56
 
57
- from pcapkit.corekit.protochain import ProtoChain
58
- from pcapkit.protocols.protocol import ProtocolBase as Protocol
59
57
  from pcapkit.protocols.schema.internet.ipv6_route import RoutingType as Schema_RoutingType
60
58
 
61
59
  TypeParser = Callable[[Schema_RoutingType, NamedArg(Schema_IPv6_Route, 'header')], Data_IPv6_Route]
@@ -402,7 +400,7 @@ class IPv6_Route(Internet[Data_IPv6_Route, Schema_IPv6_Route],
402
400
  """
403
401
  ipv6_route = Data_UnknownType(
404
402
  next=header.next,
405
- length=header.length,
403
+ length=header.length * 8 + 8,
406
404
  type=header.type,
407
405
  seg_left=header.seg_left,
408
406
  data=schema.data,
@@ -463,7 +461,7 @@ class IPv6_Route(Internet[Data_IPv6_Route, Schema_IPv6_Route],
463
461
 
464
462
  ipv6_route = Data_SourceRoute(
465
463
  next=header.next,
466
- length=header.length,
464
+ length=header.length * 8 + 8,
467
465
  type=header.type,
468
466
  seg_left=header.seg_left,
469
467
  ip=tuple(schema.ip),
@@ -507,7 +505,7 @@ class IPv6_Route(Internet[Data_IPv6_Route, Schema_IPv6_Route],
507
505
 
508
506
  ipv6_route = Data_Type2(
509
507
  next=header.next,
510
- length=header.length,
508
+ length=header.length * 8 + 8,
511
509
  type=header.type,
512
510
  seg_left=header.seg_left,
513
511
  ip=schema.ip,
@@ -547,7 +545,7 @@ class IPv6_Route(Internet[Data_IPv6_Route, Schema_IPv6_Route],
547
545
 
548
546
  ipv6_route = Data_RPL(
549
547
  next=header.next,
550
- length=header.length,
548
+ length=header.length * 8 + 8,
551
549
  type=header.type,
552
550
  seg_left=header.seg_left,
553
551
  cmpr_i=schema.cmpr_i,
@@ -72,7 +72,7 @@ class Link(Protocol[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstract-m
72
72
  #: c.f. :meth:`self._decode_next_layer <pcapkit.protocols.protocol.Protocol._decode_next_layer>`
73
73
  #: & :meth:`self._import_next_layer <pcapkit.protocols.protocol.Protocol._import_next_layer>`.
74
74
  __proto__ = collections.defaultdict(
75
- lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'), # type: ignore[arg-type,return-value]
75
+ lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
76
76
  {
77
77
  Enum_EtherType.Address_Resolution_Protocol: ModuleDescriptor('pcapkit.protocols.link.arp', 'ARP'),
78
78
  Enum_EtherType.Reverse_Address_Resolution_Protocol: ModuleDescriptor('pcapkit.protocols.link.rarp', 'RARP'),
@@ -88,7 +88,7 @@ class Frame(Protocol[Data_Frame, Schema_Frame],
88
88
  #: The values should be a tuple representing the module name and class name, or
89
89
  #: a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
90
90
  __proto__ = collections.defaultdict(
91
- lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'), # type: ignore[return-value,arg-type]
91
+ lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
92
92
  {
93
93
  Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
94
94
  Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
@@ -524,7 +524,7 @@ class PCAPNG(Protocol[Data_PCAPNG, Schema_PCAPNG],
524
524
  #: The values should be a tuple representing the module name and class name,
525
525
  #: or a :class:`~pcapkit.protocols.protocol.Protocol` subclass.
526
526
  __proto__ = collections.defaultdict(
527
- lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'), # type: ignore[arg-type,return-value]
527
+ lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
528
528
  {
529
529
  Enum_LinkType.ETHERNET: ModuleDescriptor('pcapkit.protocols.link', 'Ethernet'),
530
530
  Enum_LinkType.IPV4: ModuleDescriptor('pcapkit.protocols.internet', 'IPv4'),
@@ -862,7 +862,10 @@ class PCAPNG(Protocol[Data_PCAPNG, Schema_PCAPNG],
862
862
  self._byte = self._ctx.section.byteorder
863
863
  packet['byteorder'] = self._byte
864
864
  self.__header__ = cast('Schema_PCAPNG', self.__schema__.unpack(self._file, length, packet)) # type: ignore[call-arg,misc]
865
- return self.read(length, **kwargs)
865
+
866
+ data = self.read(length, **kwargs)
867
+ data.__update__(packet=self.packet.payload)
868
+ return data
866
869
 
867
870
  def read(self, length: 'Optional[int]' = None, *, _read: 'bool' = True,
868
871
  _seek_set: 'int' = 0, **kwargs: 'Any') -> 'Data_PCAPNG':
@@ -79,7 +79,6 @@ class Raw(Protocol[Data_Raw, Schema_Raw],
79
79
  """
80
80
  raw = Data_Raw(
81
81
  protocol=alias,
82
- packet=self._data,
83
82
  error=error,
84
83
  )
85
84
 
@@ -116,7 +116,7 @@ class ProtocolBase(Generic[_PT, _ST], metaclass=ProtocolMeta):
116
116
  #: The values should be a tuple representing the module name and class name,
117
117
  #: or a :class:`Protocol` subclass.
118
118
  __proto__: 'DefaultDict[int, ModuleDescriptor[ProtocolBase] | Type[ProtocolBase]]' = collections.defaultdict(
119
- lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'), # type: ignore[return-value,arg-type]
119
+ lambda: ModuleDescriptor('pcapkit.protocols.misc.raw', 'Raw'),
120
120
  )
121
121
 
122
122
  ##########################################################################
@@ -520,6 +520,9 @@ class ProtocolBase(Generic[_PT, _ST], metaclass=ProtocolMeta):
520
520
  # post-init customisations
521
521
  self.__post_init__(file, length, **kwargs) # type: ignore[arg-type]
522
522
 
523
+ # inject packet payload to the info dict
524
+ self._info.__update__(packet=self.packet.payload)
525
+
523
526
  @overload
524
527
  def __post_init__(self, file: 'IO[bytes] | bytes', length: 'Optional[int]' = ..., **kwargs: 'Any') -> 'None': ...
525
528
  @overload
@@ -50,7 +50,6 @@ __all__ = [
50
50
  'HIP_RelayToParameter', 'HIP_RouteViaParameter', 'HIP_FromParameter',
51
51
  'HIP_RVSHMACParameter', 'HIP_RelayHMACParameter',
52
52
  'IPv4',
53
- 'IPv4_OptionType',
54
53
  'IPv4_UnassignedOption', 'IPv4_EOOLOption', 'IPv4_NOPOption',
55
54
  'IPv4_SECOption', 'IPv4_LSROption', 'IPv4_TSOption',
56
55
  'IPv4_ESECOption', 'IPv4_RROption', 'IPv4_SIDOption',