From 6f1c4eada213e9fba1305ac9c9d311fe34efa2f4 Mon Sep 17 00:00:00 2001 From: Jarry Shaw Date: Thu, 15 Oct 2026 11:16:49 -0400 Subject: [PATCH] docs(protocols): version directives and accurate prose for the internet layer (#1103) Version directives, all 1.5.0: - versionchanged on IPv4, IPv6, HIP, HOPOPT, IPv6_Opts, IPv6_Route, IPv6_Frag, MH, IPX, AH and Internet, naming each breaking fix's issues. - versionadded on IPv6_Ext and the esp module; versionremoved for SolutionParameter.lifetime, RPL.cmpr_i/cmpr_e and the IPv6-Opts SMF_DPD test field. Accuracy: - Header tables name the info keys and fields the data models carry (IPv4, IPv6, IPv6-Opts, IPv6-Frag, AH, HIP); "Header Extension Length". - ip.rst no longer lists IPsec as an IP subclass; ipsec.rst drops an *args parameter the class does not take. - HIP's parameter table lists R1_Counter (128); the IPv4 TS and HIP ECHO_RESPONSE_UNSIGNED makers document overflow and opaque. - IP and IPv6 cite RFC 8200; AH links its defining module. Rendering: unresolved references retargeted (ESP, HIP, MH, SA), a role split across lines rejoined, and the pages gain the Internet.from_data, IPv6._import_next_layer, alias and jumbogram helper entries they cite. Refs #1103 --- docs/source/pcapkit/protocols/internet/ah.rst | 2 +- .../source/pcapkit/protocols/internet/esp.rst | 2 + .../source/pcapkit/protocols/internet/hip.rst | 6 +- .../pcapkit/protocols/internet/hopopt.rst | 3 +- .../pcapkit/protocols/internet/internet.rst | 1 + docs/source/pcapkit/protocols/internet/ip.rst | 5 +- .../pcapkit/protocols/internet/ipsec.rst | 3 - .../pcapkit/protocols/internet/ipv6.rst | 7 +++ .../pcapkit/protocols/internet/ipv6_frag.rst | 10 ++-- .../pcapkit/protocols/internet/ipv6_opts.rst | 3 +- .../pcapkit/protocols/internet/ipv6_route.rst | 2 +- pcapkit/protocols/internet/ah.py | 9 ++- pcapkit/protocols/internet/esp.py | 13 ++-- pcapkit/protocols/internet/hip.py | 24 +++++++- pcapkit/protocols/internet/hopopt.py | 13 ++++ pcapkit/protocols/internet/internet.py | 6 ++ pcapkit/protocols/internet/ip.py | 2 +- pcapkit/protocols/internet/ipv4.py | 60 +++++++++++++------ pcapkit/protocols/internet/ipv6.py | 35 +++++++---- pcapkit/protocols/internet/ipv6_ext.py | 2 + pcapkit/protocols/internet/ipv6_frag.py | 18 ++++-- pcapkit/protocols/internet/ipv6_opts.py | 19 +++++- pcapkit/protocols/internet/ipv6_route.py | 13 ++++ pcapkit/protocols/internet/ipx.py | 12 +++- pcapkit/protocols/internet/mh.py | 18 +++++- pcapkit/protocols/schema/internet/hip.py | 9 ++- .../protocols/schema/internet/ipv6_opts.py | 9 ++- .../protocols/schema/internet/ipv6_route.py | 16 +++-- 28 files changed, 246 insertions(+), 76 deletions(-) diff --git a/docs/source/pcapkit/protocols/internet/ah.rst b/docs/source/pcapkit/protocols/internet/ah.rst index b734034a49..975c3a29d7 100644 --- a/docs/source/pcapkit/protocols/internet/ah.rst +++ b/docs/source/pcapkit/protocols/internet/ah.rst @@ -14,7 +14,7 @@ Octets Bits Name Description ======= ========= ======================= =================================== 0 0 ``ah.next`` Next Header 1 8 ``ah.length`` Payload Length - 2 16 Reserved (must be zero) + 2 16 ``ah.reserved`` Reserved (must be zero) 4 32 ``ah.spi`` Security Parameters Index (SPI) 8 64 ``ah.seq`` Sequence Number Field 12 96 ``ah.icv`` Integrity Check Value (ICV) diff --git a/docs/source/pcapkit/protocols/internet/esp.rst b/docs/source/pcapkit/protocols/internet/esp.rst index b8de772c4a..459765399a 100644 --- a/docs/source/pcapkit/protocols/internet/esp.rst +++ b/docs/source/pcapkit/protocols/internet/esp.rst @@ -37,6 +37,8 @@ negotiated out of band. Therefore: ``Pad Length``, and dispatches the recovered plaintext to the next layer using ``Next Header`` -- so an ESP tunnelled TCP segment decodes as TCP. +.. versionadded:: 1.5.0 + .. autoclass:: pcapkit.protocols.internet.esp.ESP :no-members: :show-inheritance: diff --git a/docs/source/pcapkit/protocols/internet/hip.rst b/docs/source/pcapkit/protocols/internet/hip.rst index 29a4eac7ad..564867f3b0 100644 --- a/docs/source/pcapkit/protocols/internet/hip.rst +++ b/docs/source/pcapkit/protocols/internet/hip.rst @@ -14,11 +14,11 @@ Octets Bits Name Description ======= ========= ====================== ================================== 0 0 ``hip.next`` Next Header 1 8 ``hip.length`` Header Length - 2 16 Reserved (``\x00``) + 2 16 ``hip.packet_fixed`` Reserved (``\x00``) 2 17 ``hip.type`` Packet Type 3 24 ``hip.version`` Version - 3 28 Reserved - 3 31 Reserved (``\x01``) + 3 28 ``hip.reserved`` Reserved + 3 31 ``hip.version_fixed`` Reserved (``\x01``) 4 32 ``hip.chksum`` Checksum 6 48 ``hip.control`` Controls 8 64 ``hip.shit`` Sender's Host Identity Tag diff --git a/docs/source/pcapkit/protocols/internet/hopopt.rst b/docs/source/pcapkit/protocols/internet/hopopt.rst index 177d0bdba5..2b9e7c6e8d 100644 --- a/docs/source/pcapkit/protocols/internet/hopopt.rst +++ b/docs/source/pcapkit/protocols/internet/hopopt.rst @@ -13,7 +13,7 @@ described as below: Octets Bits Name Description ======= ========= =================== ================================= 0 0 ``hopopt.next`` Next Header - 1 8 ``hopopt.length`` Header Extensive Length + 1 8 ``hopopt.length`` Header Extension Length 2 16 ``hopopt.options`` Options ======= ========= =================== ================================= @@ -22,6 +22,7 @@ Octets Bits Name Description :show-inheritance: .. autoproperty:: name + .. autoproperty:: alias .. autoproperty:: length .. autoproperty:: payload .. autoproperty:: protocol diff --git a/docs/source/pcapkit/protocols/internet/internet.rst b/docs/source/pcapkit/protocols/internet/internet.rst index 065a106f9e..4d2b698140 100644 --- a/docs/source/pcapkit/protocols/internet/internet.rst +++ b/docs/source/pcapkit/protocols/internet/internet.rst @@ -15,6 +15,7 @@ which is a base class for internet layer protocols, eg. :class:`~pcapkit.protoco .. autoproperty:: layer .. automethod:: register + .. automethod:: from_data .. automethod:: _decode_next_layer .. automethod:: _import_next_layer diff --git a/docs/source/pcapkit/protocols/internet/ip.rst b/docs/source/pcapkit/protocols/internet/ip.rst index f151f40eb5..4f30ec63f8 100644 --- a/docs/source/pcapkit/protocols/internet/ip.rst +++ b/docs/source/pcapkit/protocols/internet/ip.rst @@ -7,9 +7,8 @@ IP - Internet Protocol :class:`~pcapkit.protocols.internet.ip.IP` only, which is a base class for Internet Protocol (IP) protocol family [*]_, eg. -:class:`~pcapkit.protocols.internet.ipv4.IPv4`, -:class:`~pcapkit.protocols.internet.ipv6.IPv6`, and -:class:`~pcapkit.protocols.internet.ipsec.IPsec`. +:class:`~pcapkit.protocols.internet.ipv4.IPv4` and +:class:`~pcapkit.protocols.internet.ipv6.IPv6`. .. autoclass:: pcapkit.protocols.internet.ip.IP :no-members: diff --git a/docs/source/pcapkit/protocols/internet/ipsec.rst b/docs/source/pcapkit/protocols/internet/ipsec.rst index 8180ae8f15..e18cf64213 100644 --- a/docs/source/pcapkit/protocols/internet/ipsec.rst +++ b/docs/source/pcapkit/protocols/internet/ipsec.rst @@ -14,9 +14,6 @@ Security (IPsec) protocol family [*]_, eg. :no-members: :show-inheritance: - :param \*args: Arbitrary positional arguments. - :param \*\*kwargs: Arbitrary keyword arguments. - .. automethod:: id .. rubric:: Footnotes diff --git a/docs/source/pcapkit/protocols/internet/ipv6.rst b/docs/source/pcapkit/protocols/internet/ipv6.rst index e2aedb2c10..0080492147 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6.rst @@ -41,6 +41,7 @@ Octets Bits Name Description .. automethod:: _make_data .. automethod:: _decode_next_layer + .. automethod:: _import_next_layer .. automethod:: __index__ @@ -84,6 +85,12 @@ Type Stubs Flow label. +Auxiliary Functions +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: pcapkit.protocols.schema.internet.ipv6.jumbo_payload_length +.. autofunction:: pcapkit.protocols.schema.internet.ipv6.jumbogram_error + Data Models ----------- diff --git a/docs/source/pcapkit/protocols/internet/ipv6_frag.rst b/docs/source/pcapkit/protocols/internet/ipv6_frag.rst index 397dfb532e..0e3453689f 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6_frag.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6_frag.rst @@ -9,16 +9,16 @@ only, which implements extractor for Fragment Header for IPv6 (IPv6-Frag) [*]_, whose structure is described as below: -======= ========= ==================== ======================= +======= ========= ========================= ======================= Octets Bits Name Description -======= ========= ==================== ======================= +======= ========= ========================= ======================= 0 0 ``frag.next`` Next Header - 1 8 Reserved + 1 8 ``frag.reserved_octet`` Reserved 2 16 ``frag.offset`` Fragment Offset - 3 29 Reserved + 3 29 ``frag.reserved`` Reserved 3 31 ``frag.mf`` More Flag 4 32 ``frag.id`` Identification -======= ========= ==================== ======================= +======= ========= ========================= ======================= .. autoclass:: pcapkit.protocols.internet.ipv6_frag.IPv6_Frag :no-members: diff --git a/docs/source/pcapkit/protocols/internet/ipv6_opts.rst b/docs/source/pcapkit/protocols/internet/ipv6_opts.rst index bb8a2ce144..83b1ecd38c 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6_opts.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6_opts.rst @@ -13,7 +13,7 @@ as below: Octets Bits Name Description ======= ========= =================== ================================= 0 0 ``opts.next`` Next Header - 1 8 ``opts.length`` Header Extensive Length + 1 8 ``opts.length`` Header Extension Length 2 16 ``opts.options`` Options ======= ========= =================== ================================= @@ -22,6 +22,7 @@ Octets Bits Name Description :show-inheritance: .. autoproperty:: name + .. autoproperty:: alias .. autoproperty:: length .. autoproperty:: payload .. autoproperty:: protocol diff --git a/docs/source/pcapkit/protocols/internet/ipv6_route.rst b/docs/source/pcapkit/protocols/internet/ipv6_route.rst index 70cfe09892..25c64fa50b 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6_route.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6_route.rst @@ -12,7 +12,7 @@ only, which implements extractor for Routing Header for IPv6 Octets Bits Name Description ======= ========= ==================== =============================== 0 0 ``route.next`` Next Header - 1 8 ``route.length`` Header Extensive Length + 1 8 ``route.length`` Header Extension Length 2 16 ``route.type`` Routing Type 3 24 ``route.seg_left`` Segments Left 4 32 ``route.data`` Type-Specific Data diff --git a/pcapkit/protocols/internet/ah.py b/pcapkit/protocols/internet/ah.py index 0325c32abc..cd2f9959d5 100644 --- a/pcapkit/protocols/internet/ah.py +++ b/pcapkit/protocols/internet/ah.py @@ -5,7 +5,7 @@ .. module:: pcapkit.protocols.internet.ah :mod:`pcapkit.protocols.internet.ah` contains -:class:`~pcapkit.protocols.internet.AH` only, +:class:`~pcapkit.protocols.internet.ah.AH` only, which implements extractor for Authentication Header (AH) [*]_, whose structure is described as below: @@ -15,7 +15,7 @@ ======= ========= ======================= =================================== 0 0 ``ah.next`` Next Header 1 8 ``ah.length`` Payload Length - 2 16 Reserved (must be zero) + 2 16 ``ah.reserved`` Reserved (must be zero) 4 32 ``ah.spi`` Security Parameters Index (SPI) 8 64 ``ah.seq`` Sequence Number Field 12 96 ``ah.icv`` Integrity Check Value (ICV) @@ -65,6 +65,11 @@ class AH(IPsec[Data_AH, Schema_AH], IPv6_Ext[Data_AH, Schema_AH], :class:`~pcapkit.protocols.internet.ipsec.IPsec` comes first so that its :meth:`~pcapkit.protocols.internet.ipsec.IPsec.id` takes precedence. + .. versionchanged:: 1.5.0 + + A rebuild writes the reserved field back as captured rather than as + zero (:issue:`1327`). + """ ########################################################################## diff --git a/pcapkit/protocols/internet/esp.py b/pcapkit/protocols/internet/esp.py index be4764f9de..d2ad231400 100644 --- a/pcapkit/protocols/internet/esp.py +++ b/pcapkit/protocols/internet/esp.py @@ -160,6 +160,8 @@ .. [*] https://en.wikipedia.org/wiki/IPsec +.. versionadded:: 1.5.0 + """ import enum import hashlib @@ -502,7 +504,8 @@ class SecurityAssociation: unless ``salt`` is given separately. salt: AEAD salt, when not appended to ``encryption_key``. integrity: Integrity algorithm, c.f. :meth:`IntegritySuite.get`. Must - be :attr:`Integrity.NONE` for an AEAD suite, which provides its own. + be :attr:`Integrity.NONE ` + for an AEAD suite, which provides its own. integrity_key: Integrity key. icv_length: Override for the ICV length, in octets. Needed for the long standing implementation bug noted in :rfc:`8221` ยง6, where @@ -984,9 +987,11 @@ class ESP(IPsec[Data_ESP, Schema_ESP], IPv6_Ext[Data_ESP, Schema_ESP], next-layer protocol in IPv4, so it also travels directly as an IPv4 payload, which is what qualifies it for a base besides :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext`. - :attr:`payload` and :attr:`protochain` come from - :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext`; :attr:`protocol` - is spelled out below for the reason given there. + :attr:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext.payload` and + :attr:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext.protochain` come from + :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext`; ``protocol`` is + spelled out here for the reason given on + :attr:`IPv6_Ext.protocol `. Note: :rfc:`8200#section-4.5` says outright that ESP "is not considered an diff --git a/pcapkit/protocols/internet/hip.py b/pcapkit/protocols/internet/hip.py index 49e000460d..4b1f3323d1 100644 --- a/pcapkit/protocols/internet/hip.py +++ b/pcapkit/protocols/internet/hip.py @@ -15,11 +15,11 @@ ======= ========= ====================== ================================== 0 0 ``hip.next`` Next Header 1 8 ``hip.length`` Header Length - 2 16 Reserved (``\\x00``) + 2 16 ``hip.packet_fixed`` Reserved (``\\x00``) 2 17 ``hip.type`` Packet Type 3 24 ``hip.version`` Version 3 28 ``hip.reserved`` Reserved - 3 31 Reserved (``\\x01``) + 3 31 ``hip.version_fixed`` Reserved (``\\x01``) 4 32 ``hip.chksum`` Checksum 6 48 ``hip.control`` Controls 8 64 ``hip.shit`` Sender's Host Identity Tag @@ -300,6 +300,8 @@ class HIP(IPv6_Ext[Data_HIP, Schema_HIP], Internet[Data_HIP, Schema_HIP], - Parameter Parser * - :attr:`~pcapkit.const.hip.parameter.Parameter.ESP_INFO` - :meth:`~pcapkit.protocols.internet.hip.HIP._read_param_esp_info` + * - :attr:`~pcapkit.const.hip.parameter.Parameter.R1_Counter` + - :meth:`~pcapkit.protocols.internet.hip.HIP._read_param_r1_counter` * - :attr:`~pcapkit.const.hip.parameter.Parameter.R1_COUNTER` - :meth:`~pcapkit.protocols.internet.hip.HIP._read_param_r1_counter` * - :attr:`~pcapkit.const.hip.parameter.Parameter.LOCATOR_SET` @@ -395,6 +397,20 @@ class HIP(IPv6_Ext[Data_HIP, Schema_HIP], Internet[Data_HIP, Schema_HIP], * - :attr:`~pcapkit.const.hip.parameter.Parameter.RELAY_HMAC` - :meth:`~pcapkit.protocols.internet.hip.HIP._read_param_relay_hmac` + .. versionchanged:: 1.5.0 + + * Parameters dispatch through :attr:`__parameter__` rather than by + method name (:issue:`429`). + * A parameter is padded to the record length :rfc:`7401` gives + (:issue:`651`), and ``PUZZLE``, ``SOLUTION``, ``R1_COUNTER`` and + ``LOCATOR_SET`` are sized as the RFCs give them (:issue:`608`, + :issue:`653` to :issue:`655`, :issue:`672`, :issue:`679`). + * A rebuild reproduces the Header Length, a packet with no parameters, + the ``PUZZLE`` lifetime, the reserved, padding and Locator flag bits, + and the two fixed header bits (:issue:`1313`, :issue:`1314`, + :issue:`1323`, :issue:`1328`, :issue:`1365`, :issue:`1417`, + :issue:`1459`). + """ ########################################################################## @@ -3526,7 +3542,8 @@ def _make_param_solution(self, code: 'Enum_Parameter', param: 'Optional[Data_Sol rewriting it, and to that mandated zero otherwise. Pass it explicitly to override either -- notably to write the conformant zero over a non-conformant one received from a peer, which is - otherwise unreachable because :class:`Data_SolutionParameter` is + otherwise unreachable because + :class:`~pcapkit.protocols.data.internet.hip.SolutionParameter` is immutable opaque: opaque data random: random #I value @@ -4996,6 +5013,7 @@ def _make_param_echo_response_unsigned(self, code: 'Enum_Parameter', param: 'Opt code: parameter code param: parameter data version: HIP protocol version + opaque: opaque data Returns: HIP parameter schema. diff --git a/pcapkit/protocols/internet/hopopt.py b/pcapkit/protocols/internet/hopopt.py index 377975a1f7..c3e72f5953 100644 --- a/pcapkit/protocols/internet/hopopt.py +++ b/pcapkit/protocols/internet/hopopt.py @@ -184,6 +184,19 @@ class HOPOPT(IPv6_Ext[Data_HOPOPT, Schema_HOPOPT], - :meth:`~pcapkit.protocols.internet.hopopt.HOPOPT._read_opt_ip_dff` - :meth:`~pcapkit.protocols.internet.hopopt.HOPOPT._make_opt_ip_dff` + .. versionchanged:: 1.5.0 + + * The ILNP nonce is sized with a ceiling rather than a floor + (:issue:`601`). + * The RPL option keeps its reserved flag bits on rebuild and accepts + :rfc:`6553` sub-TLVs (:issue:`1199`). + * A rebuild reproduces the option area byte for byte: its padding, a + PadN with no data, the SMF_DPD, CALIPSO, PDM and ILNP Nonce options, + and unassigned Quick-Start function codes (:issue:`1200`, + :issue:`1228`, :issue:`1229`, :issue:`1232` to :issue:`1234`, + :issue:`1237`); a CALIPSO option keeps its trailing pad and its + length (:issue:`1403`). + """ ########################################################################## diff --git a/pcapkit/protocols/internet/internet.py b/pcapkit/protocols/internet/internet.py index d3a04cd097..934d9f73f4 100644 --- a/pcapkit/protocols/internet/internet.py +++ b/pcapkit/protocols/internet/internet.py @@ -94,6 +94,12 @@ class Internet(ProtocolBase[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=ab * - :attr:`~pcapkit.const.reg.transtype.TransType.OSPFIGP` - :class:`pcapkit.protocols.application.ospf.OSPF` + .. versionchanged:: 1.5.0 + + A layer parsed as an IPv6 extension header keeps only its own octets in + :attr:`data`, so that ``from_data(info).data`` rebuilds it exactly + (:issue:`1446`). + """ ########################################################################## diff --git a/pcapkit/protocols/internet/ip.py b/pcapkit/protocols/internet/ip.py index eb680b956a..87bcde0371 100644 --- a/pcapkit/protocols/internet/ip.py +++ b/pcapkit/protocols/internet/ip.py @@ -29,7 +29,7 @@ class IP(Internet[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=abstract-met """Base class for the IP protocol family. - Internet Protocol version 4 (:class:`~pcapkit.protocols.internet.ipv4.IPv4`) [:rfc:`791`] - - Internet Protocol version 6 (:class:`~pcapkit.protocols.internet.ipv6.IPv6`) [:rfc:`2460`] + - Internet Protocol version 6 (:class:`~pcapkit.protocols.internet.ipv6.IPv6`) [:rfc:`8200`] The IPsec protocols (:class:`~pcapkit.protocols.internet.ah.AH` and :class:`~pcapkit.protocols.internet.esp.ESP`) derive from diff --git a/pcapkit/protocols/internet/ipv4.py b/pcapkit/protocols/internet/ipv4.py index 782f0e096a..416986946f 100644 --- a/pcapkit/protocols/internet/ipv4.py +++ b/pcapkit/protocols/internet/ipv4.py @@ -13,25 +13,25 @@ ======= ========= ====================== ============================================= Octets Bits Name Description ======= ========= ====================== ============================================= - 0 0 ``ip.version`` Version (``4``) - 0 4 ``ip.hdr_len`` Internal Header Length (IHL) - 1 8 ``ip.tos.pre`` ToS Precedence - 1 11 ``ip.tos.del`` ToS Delay - 1 12 ``ip.tos.thr`` ToS Throughput - 1 13 ``ip.tos.rel`` ToS Reliability - 1 14 ``ip.tos.ecn`` Explicit Congestion Notification (ECN) - 2 16 ``ip.len`` Total Length - 4 32 ``ip.id`` Identification - 6 48 Reserved Bit (must be ``\\x00``) - 6 49 ``ip.flags.df`` Don't Fragment (DF) - 6 50 ``ip.flags.mf`` More Fragments (MF) - 6 51 ``ip.offset`` Fragment Offset - 8 64 ``ip.ttl`` Time To Live (TTL) - 9 72 ``ip.protocol`` Protocol (Transport Layer) - 10 80 ``ip.checksum`` Header Checksum - 12 96 ``ip.src`` Source IP Address - 16 128 ``ip.dst`` Destination IP Address - 20 160 ``ip.options`` IP Options (if IHL > ``5``) + 0 0 ``ipv4.version`` Version (``4``) + 0 4 ``ipv4.hdr_len`` Internet Header Length (IHL) + 1 8 ``ipv4.tos.pre`` Precedence + 1 11 ``ipv4.tos.del`` Delay + 1 12 ``ipv4.tos.thr`` Throughput + 1 13 ``ipv4.tos.rel`` Reliability + 1 14 ``ipv4.tos.ecn`` Explicit Congestion Notification (ECN) + 2 16 ``ipv4.len`` Total Length + 4 32 ``ipv4.id`` Identification + 6 48 Reserved Bit (must be ``\\x00``) + 6 49 ``ipv4.flags.df`` Don't Fragment (DF) + 6 50 ``ipv4.flags.mf`` More Fragments (MF) + 6 51 ``ipv4.offset`` Fragment Offset + 8 64 ``ipv4.ttl`` Time To Live (TTL) + 9 72 ``ipv4.protocol`` Protocol (Transport Layer) + 10 80 ``ipv4.checksum`` Header Checksum + 12 96 ``ipv4.src`` Source IP Address + 16 128 ``ipv4.dst`` Destination IP Address + 20 160 ``ipv4.options`` IP Options (if IHL > ``5``) ======= ========= ====================== ============================================= .. [*] https://en.wikipedia.org/wiki/IPv4 @@ -186,6 +186,26 @@ class IPv4(IP[Data_IPv4, Schema_IPv4], - :meth:`~pcapkit.protocols.internet.ipv4.IPv4._read_opt_qs` - :meth:`~pcapkit.protocols.internet.ipv4.IPv4._make_opt_qs` + .. versionchanged:: 1.5.0 + + * Options dispatch through :attr:`__option__` rather than by method + name (:issue:`429`). + * A rebuild keeps the fragment offset in 8-octet units, and a header + without options rebuilds (:issue:`494`). + * A rebuild from :meth:`from_data` keeps the Total Length a truncated + capture declares (:issue:`1155`), and the octets past it as + :attr:`~pcapkit.protocols.schema.internet.ipv4.IPv4.trailer` + (:issue:`1209`). + * A header length declared past the data raises + :exc:`~pcapkit.utilities.exceptions.ProtocolError` on read + (:issue:`1404`). + * A rebuild reproduces the option area, the route and timestamp slots, + the SEC and TS fields and the reserved bits byte for byte + (:issue:`1316` to :issue:`1322`, :issue:`1326`, :issue:`1349`, + :issue:`1391` to :issue:`1393`). + * The TS option's maker takes an address as a string as well + (:issue:`1402`). + """ ########################################################################## @@ -1665,6 +1685,8 @@ def _make_opt_ts(self, kind: 'Enum_OptionNumber', option: 'Optional[Data_TSOptio kind: option type code option: option data counts: maximum number of timestamps to record + overflow: overflow count, i.e. the number of modules that could not + register a timestamp (:rfc:`791#section-3.1`) timestamp: list of timestamps, i.e. the slots before the pointer, or a mapping of the addresses to their timestamps; an address may be anything :func:`~pcapkit.corekit.fields.ipaddress.parse_ip_address` diff --git a/pcapkit/protocols/internet/ipv6.py b/pcapkit/protocols/internet/ipv6.py index 1397f6b820..c292667747 100644 --- a/pcapkit/protocols/internet/ipv6.py +++ b/pcapkit/protocols/internet/ipv6.py @@ -13,14 +13,14 @@ ======= ========= ===================== ======================================= Octets Bits Name Description ======= ========= ===================== ======================================= - 0 0 ``ip.version`` Version (``6``) - 0 4 ``ip.class`` Traffic Class - 1 12 ``ip.label`` Flow Label - 4 32 ``ip.payload`` Payload Length (header excludes) - 6 48 ``ip.next`` Next Header - 7 56 ``ip.limit`` Hop Limit - 8 64 ``ip.src`` Source Address - 24 192 ``ip.dst`` Destination Address + 0 0 ``ipv6.version`` Version (``6``) + 0 4 ``ipv6.class`` Traffic Class + 1 12 ``ipv6.label`` Flow Label + 4 32 ``ipv6.payload`` Payload Length (header excludes) + 6 48 ``ipv6.next`` Next Header + 7 56 ``ipv6.limit`` Hop Limit + 8 64 ``ipv6.src`` Source Address + 24 192 ``ipv6.dst`` Destination Address ======= ========= ===================== ======================================= .. [*] https://en.wikipedia.org/wiki/IPv6_packet @@ -73,7 +73,22 @@ class IPv6(IP[Data_IPv6, Schema_IPv6], schema=Schema_IPv6, data=Data_IPv6): - """This class implements Internet Protocol version 6.""" + """This class implements Internet Protocol version 6. + + .. versionchanged:: 1.5.0 + + * An extension header with no dedicated parser is parsed by + :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext` + (:issue:`891`). + * A rebuild from :meth:`from_data` keeps the Payload Length a truncated + capture declares (:issue:`1155`), and the octets past it as + :attr:`~pcapkit.protocols.schema.internet.ipv6.IPv6.trailer` + (:issue:`1209`). + * Next Header codes 253 and 254 are parsed and rebuilt once + (:issue:`1231`), and a cut extension header chain rebuilds byte for + byte (:issue:`1471`, :issue:`1473`). + + """ ########################################################################## # Defaults. @@ -174,7 +189,7 @@ def read(self, length: 'Optional[int]' = None, *, __packet__: 'Optional[dict[str, Any]]' = None, **kwargs: 'Any') -> 'Data_IPv6': # pylint: disable=unused-argument """Read Internet Protocol version 6 (IPv6). - Structure of IPv6 header [:rfc:`2460`]: + Structure of IPv6 header [:rfc:`8200`]: .. code-block:: text diff --git a/pcapkit/protocols/internet/ipv6_ext.py b/pcapkit/protocols/internet/ipv6_ext.py index ace7e6464c..e2dcdb35e0 100644 --- a/pcapkit/protocols/internet/ipv6_ext.py +++ b/pcapkit/protocols/internet/ipv6_ext.py @@ -227,6 +227,8 @@ class IPv6_Ext(Internet[_PT, _ST], Generic[_PT, _ST], so ``tests/protocols/internet/test_ipv6_ext_unit.py`` does, over every subclass discovered at runtime. + .. versionadded:: 1.5.0 + """ ########################################################################## diff --git a/pcapkit/protocols/internet/ipv6_frag.py b/pcapkit/protocols/internet/ipv6_frag.py index 6f5df5aa30..d34f28a24e 100644 --- a/pcapkit/protocols/internet/ipv6_frag.py +++ b/pcapkit/protocols/internet/ipv6_frag.py @@ -10,16 +10,16 @@ IPv6 (IPv6-Frag) [*]_, whose structure is described as below: -======= ========= ==================== ======================= +======= ========= ========================= ======================= Octets Bits Name Description -======= ========= ==================== ======================= +======= ========= ========================= ======================= 0 0 ``frag.next`` Next Header - 1 8 Reserved + 1 8 ``frag.reserved_octet`` Reserved 2 16 ``frag.offset`` Fragment Offset - 3 29 Reserved + 3 29 ``frag.reserved`` Reserved 3 31 ``frag.mf`` More Flag 4 32 ``frag.id`` Identification -======= ========= ==================== ======================= +======= ========= ========================= ======================= .. [*] https://en.wikipedia.org/wiki/IPv6_packet#Fragment @@ -48,7 +48,13 @@ class IPv6_Frag(IPv6_Ext[Data_IPv6_Frag, Schema_IPv6_Frag], schema=Schema_IPv6_Frag, data=Data_IPv6_Frag): - """This class implements Fragment Header for IPv6.""" + """This class implements Fragment Header for IPv6. + + .. versionchanged:: 1.5.0 + + A rebuild keeps the reserved bits (:issue:`1235`). + + """ ########################################################################## # Properties. diff --git a/pcapkit/protocols/internet/ipv6_opts.py b/pcapkit/protocols/internet/ipv6_opts.py index c3140ccdc7..303bc4e0a5 100644 --- a/pcapkit/protocols/internet/ipv6_opts.py +++ b/pcapkit/protocols/internet/ipv6_opts.py @@ -13,9 +13,9 @@ ======= ========= =================== ================================= Octets Bits Name Description ======= ========= =================== ================================= - 0 0 ``opt.next`` Next Header - 1 8 ``opt.length`` Header Extension Length - 2 16 ``opt.options`` Options + 0 0 ``opts.next`` Next Header + 1 8 ``opts.length`` Header Extension Length + 2 16 ``opts.options`` Options ======= ========= =================== ================================= .. [*] https://en.wikipedia.org/wiki/IPv6_packet#Hop-by-hop_options_and_destination_options @@ -188,6 +188,19 @@ class IPv6_Opts(IPv6_Ext[Data_IPv6_Opts, Schema_IPv6_Opts], - :meth:`~pcapkit.protocols.internet.ipv6_opts.IPv6_Opts._read_opt_ip_dff` - :meth:`~pcapkit.protocols.internet.ipv6_opts.IPv6_Opts._make_opt_ip_dff` + .. versionchanged:: 1.5.0 + + * The ILNP nonce is sized with a ceiling rather than a floor + (:issue:`601`). + * The RPL option keeps its reserved flag bits on rebuild and accepts + :rfc:`6553` sub-TLVs (:issue:`1199`). + * A rebuild reproduces the option area byte for byte: its padding, a + PadN with no data, the SMF_DPD, CALIPSO, PDM and ILNP Nonce options, + and unassigned Quick-Start function codes (:issue:`1200`, + :issue:`1228`, :issue:`1229`, :issue:`1232` to :issue:`1234`, + :issue:`1237`); a CALIPSO option keeps its trailing pad and its + length (:issue:`1403`). + """ ########################################################################## diff --git a/pcapkit/protocols/internet/ipv6_route.py b/pcapkit/protocols/internet/ipv6_route.py index 1292b024e7..e71f7c08f7 100644 --- a/pcapkit/protocols/internet/ipv6_route.py +++ b/pcapkit/protocols/internet/ipv6_route.py @@ -92,6 +92,19 @@ class IPv6_Route(IPv6_Ext[Data_IPv6_Route, Schema_IPv6_Route], - :meth:`~pcapkit.protocols.internet.ipv6_route.IPv6_Route._read_data_type_rpl` - :meth:`~pcapkit.protocols.internet.ipv6_route.IPv6_Route._make_data_type_rpl` + .. versionchanged:: 1.5.0 + + * Hdr Ext Len is in 8-octet units both on read and on build + (:issue:`487`). + * The RPL fixed area is sized at 4 octets, per :rfc:`6554` + (:issue:`564`). + * A :obj:`bool` given as an address raises + :exc:`~pcapkit.utilities.exceptions.FieldValueError` (:issue:`540`). + * :meth:`make` takes ``data`` as :obj:`bytes` for every routing type + (:issue:`1236`), and an RPL source route rebuilds byte for byte, its + address compression and a truncated address list included + (:issue:`1456`, :issue:`1457`). + """ ########################################################################## diff --git a/pcapkit/protocols/internet/ipx.py b/pcapkit/protocols/internet/ipx.py index 9c3b7e94f5..a602f6ff61 100644 --- a/pcapkit/protocols/internet/ipx.py +++ b/pcapkit/protocols/internet/ipx.py @@ -50,7 +50,17 @@ class IPX(Internet[Data_IPX, Schema_IPX], schema=Schema_IPX, data=Data_IPX): - """This class implements Internetwork Packet Exchange.""" + """This class implements Internetwork Packet Exchange. + + .. versionchanged:: 1.5.0 + + :meth:`from_data` rebuilds a parsed packet rather than raising + :exc:`struct.error` (:issue:`1315`), and the octets past the IPX Length + field are kept as + :attr:`~pcapkit.protocols.schema.internet.ipx.IPX.trailer` + (:issue:`1433`). + + """ ########################################################################## # Properties. diff --git a/pcapkit/protocols/internet/mh.py b/pcapkit/protocols/internet/mh.py index 4c5a6c2059..b072583b39 100644 --- a/pcapkit/protocols/internet/mh.py +++ b/pcapkit/protocols/internet/mh.py @@ -1153,6 +1153,14 @@ class MH(IPv6_Ext[Data_MH, Schema_MH], - :meth:`~pcapkit.protocols.internet.mh.MH._read_ext_exp` - :meth:`~pcapkit.protocols.internet.mh.MH._make_ext_exp` + .. versionchanged:: 1.5.0 + + * The FBU and FBack Lifetime is read and built as plain seconds, per + :rfc:`5568` (:issue:`493`). + * A rebuild keeps a PadN with no data, the reserved fields, the reserved + bits of the flag fields and the octets each padding field captured + (:issue:`1324`, :issue:`1418`, :issue:`1437`). + """ ########################################################################## @@ -5566,7 +5574,9 @@ def _read_opt_ams4(self, schema: 'Schema_ActiveMulticastSubscriptionIPv4Option', The membership context is an IGMP group address (:rfc:`1112`, :rfc:`2236`) or an IGMPv3 group record (:rfc:`3376#section-4.2`), which belong to IGMP rather than to the mobility header, so they are - recorded opaquely. :attr:`igmp_type` says which: ``0x12`` IGMPv1, + recorded opaquely. + :attr:`~pcapkit.protocols.data.internet.mh.ActiveMulticastSubscriptionIPv4Option.igmp_type` + says which: ``0x12`` IGMPv1, ``0x16`` IGMPv2, ``0x22`` IGMPv3. Args: @@ -5611,7 +5621,9 @@ def _read_opt_ams6(self, schema: 'Schema_ActiveMulticastSubscriptionIPv6Option', For MLDv2 the context is an :rfc:`3810#section-5.2` multicast address record; for MLDv1 it is a reserved word followed by a multicast address [:rfc:`7161#section-4.1.3`]. Both belong to MLD, so the context is - recorded opaquely and :attr:`mld_type` says which form it is in. + recorded opaquely and + :attr:`~pcapkit.protocols.data.internet.mh.ActiveMulticastSubscriptionIPv6Option.mld_type` + says which form it is in. Args: schema: Parsed option schema. @@ -9514,7 +9526,7 @@ def _make_opt_lmaa(self, type: 'Enum_Option', option: 'Optional[Data_LMAAddressO Note: The option length is derived from the address family rather than from - :attr:`code`, so that the two cannot be emitted disagreeing. + ``code``, so that the two cannot be emitted disagreeing. """ if option is not None: diff --git a/pcapkit/protocols/schema/internet/hip.py b/pcapkit/protocols/schema/internet/hip.py index 27d8932883..34c4e5a8cb 100644 --- a/pcapkit/protocols/schema/internet/hip.py +++ b/pcapkit/protocols/schema/internet/hip.py @@ -698,7 +698,14 @@ def __init__(self, type: 'Enum_Parameter', len: 'int', index: 'int', lifetime: ' @schema_final class SolutionParameter(Parameter, code=Enum_Parameter.SOLUTION): - """Header schema for HIP ``SOLUTION`` parameters.""" + """Header schema for HIP ``SOLUTION`` parameters. + + .. versionremoved:: 1.5.0 + + ``lifetime``, now :attr:`reserved`: only ``PUZZLE`` carries a lifetime + (:issue:`654`). + + """ #: Numeric index. index: 'int' = UInt8Field() diff --git a/pcapkit/protocols/schema/internet/ipv6_opts.py b/pcapkit/protocols/schema/internet/ipv6_opts.py index d69caa3b4d..44256ad0f0 100644 --- a/pcapkit/protocols/schema/internet/ipv6_opts.py +++ b/pcapkit/protocols/schema/internet/ipv6_opts.py @@ -371,7 +371,14 @@ class SMFDPDOption(Option, EnumSchema[Enum_SMFDPDMode]): @schema_final class SMFIdentificationBasedDPDOption(SMFDPDOption, code=Enum_SMFDPDMode.I_DPD): - """Header schema for IPv6-Opts SMF identification-based DPD options.""" + """Header schema for IPv6-Opts SMF identification-based DPD options. + + .. versionremoved:: 1.5.0 + + ``test``, a field the HOPOPT schema lacks, so that the same octets + parse alike under both headers (:issue:`441`). + + """ #: TaggerID information. info: 'TaggerIDInfo' = BitField(length=1, namespace={ diff --git a/pcapkit/protocols/schema/internet/ipv6_route.py b/pcapkit/protocols/schema/internet/ipv6_route.py index 0ef04791dd..b7a08c717e 100644 --- a/pcapkit/protocols/schema/internet/ipv6_route.py +++ b/pcapkit/protocols/schema/internet/ipv6_route.py @@ -80,9 +80,10 @@ def ipv6_route_header_length(hdr_ext_len: 'int') -> 'int': ``4 + 8 * hdr_ext_len`` there), not a duplicate of it. It is what each ``_read_data_type_*`` in :mod:`pcapkit.protocols.internet.ipv6_route` reports back as the parsed - route data's own ``.length``, which :meth:`~pcapkit.protocols.internet. - ipv6_route.IPv6_Route.read` then subtracts from the outer packet length - to find the next layer's length. It is the read-side counterpart of + route data's own ``.length``, which + :meth:`~pcapkit.protocols.internet.ipv6_route.IPv6_Route.read` then + subtracts from the outer packet length to find the next layer's length. + It is the read-side counterpart of :meth:`~pcapkit.protocols.internet.ipv6_route.IPv6_Route._make_hdr_ext_len`, which does the inverse arithmetic on the write side. @@ -185,7 +186,14 @@ def __init__(self, reserved: 'bytes', ip: 'IPv6Address | str | int | bytes') -> @schema_final class RPL(RoutingType, code=Enum_Routing.RPL_Source_Route_Header): - """Header schema for IPv6-Route RPL routing data.""" + """Header schema for IPv6-Route RPL routing data. + + .. versionremoved:: 1.5.0 + + ``cmpr_i`` and ``cmpr_e``, now the keys of :attr:`cmpr` + (:issue:`1456`). + + """ #: CmprI and CmprE -- two 4-bit counts sharing one octet. #: