From 4ca60c009d4fe83cac3c5ceaf77115c628a22526 Mon Sep 17 00:00:00 2001 From: Jarry Shaw Date: Thu, 15 Oct 2026 12:56:52 -0400 Subject: [PATCH] docs(protocols): second pass over HIP, IPv4, IPv6 and IPX (#1103) Reads what phase 1 left unread: HIP, its schema and data model, the IPv4 makers from TR on, and the IPv4 schema and data model. - test_docstring_contract: drop the two ipv4.py pins this fixes, point the Vendor.context reason at default.py:417, and say none is excused. - internet: drop the beta-only EXTENSION_HEADER_LIMIT versionremoved. - HIP data model: versionremoved for SolutionParameter.lifetime (#654). - HIP: **kwargs on 11 makers, Raises completed on six methods, RFC cites for OVERLAY_TTL and VIA_RVS, "schama" typo throughout. - HIP schema and data: parameter names, two typos, the locator and host identity selector cases, the TF list item widths. - IPv4 schema: the QS function lookup admits 0 to 15, not 0 to 8. - IPv6: the #891 bullet names both paths to IPv6_Ext, and __generic_ext_codes__ is rendered with its IPv6_Ext link resolved. - from_data, from_dict and data references fixed. AST identical bar the three permitted test entries; tests pass. Refs #1103 --- .../pcapkit/protocols/internet/internet.rst | 6 - .../pcapkit/protocols/internet/ipv6.rst | 3 + pcapkit/protocols/data/internet/hip.py | 15 +- pcapkit/protocols/data/internet/ipv4.py | 6 +- pcapkit/protocols/data/internet/ipv6.py | 3 +- pcapkit/protocols/internet/hip.py | 137 +++++++++++------- pcapkit/protocols/internet/internet.py | 8 +- pcapkit/protocols/internet/ipv4.py | 12 +- pcapkit/protocols/internet/ipv6.py | 20 ++- pcapkit/protocols/internet/ipx.py | 3 +- pcapkit/protocols/schema/internet/hip.py | 24 +-- pcapkit/protocols/schema/internet/ipv4.py | 6 +- tests/test_docstring_contract.py | 17 +-- 13 files changed, 147 insertions(+), 113 deletions(-) diff --git a/docs/source/pcapkit/protocols/internet/internet.rst b/docs/source/pcapkit/protocols/internet/internet.rst index 4d2b698140..8c3b9d59c9 100644 --- a/docs/source/pcapkit/protocols/internet/internet.rst +++ b/docs/source/pcapkit/protocols/internet/internet.rst @@ -46,9 +46,3 @@ behind IPv4, its toolkit steps over them in the octets to find TCP, up to :data:`~pcapkit.utilities.config.EXTENSION_HEADER_LIMIT` of them in a row. The ``pypcapfile`` toolkit walks no extension header chain, so it finds no upper layer behind one. - -.. versionremoved:: 1.5.0 - - ``pcapkit.protocols.internet.internet.EXTENSION_HEADER_LIMIT``, now - :data:`pcapkit.utilities.config.EXTENSION_HEADER_LIMIT`, set with - :envvar:`PCAPKIT_EXTENSION_HEADER_LIMIT` (:issue:`1726`). diff --git a/docs/source/pcapkit/protocols/internet/ipv6.rst b/docs/source/pcapkit/protocols/internet/ipv6.rst index 0080492147..2468e839dc 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6.rst @@ -45,6 +45,9 @@ Octets Bits Name Description .. automethod:: __index__ + .. autoattribute:: __generic_ext_codes__ + :no-value: + Protocol Constants ------------------ diff --git a/pcapkit/protocols/data/internet/hip.py b/pcapkit/protocols/data/internet/hip.py index d6c1227c3b..3a86d7bdc0 100644 --- a/pcapkit/protocols/data/internet/hip.py +++ b/pcapkit/protocols/data/internet/hip.py @@ -252,7 +252,14 @@ def __init__(self, type: 'Enum_Parameter', critical: 'bool', length: 'int', inde @info_final class SolutionParameter(Parameter): - """Data model for HIP ``SOLUTION`` parameter.""" + """Data model for HIP ``SOLUTION`` parameter. + + .. versionremoved:: 1.5.0 + + ``lifetime``, now :attr:`reserved`: only ``PUZZLE`` carries a lifetime + (:issue:`654`). + + """ #: Numeric index. index: 'int' @@ -431,7 +438,7 @@ def __init__(self, type: 'Enum_Parameter', critical: 'bool', length: 'int', hi_l @info_final class HITSuiteListParameter(Parameter): - """Data model for HIP ``HIST_SUITE_LIST`` parameter.""" + """Data model for HIP ``HIT_SUITE_LIST`` parameter.""" #: Suite IDs. suite_id: 'tuple[HITSuite, ...]' @@ -654,7 +661,7 @@ def __init__(self, type: 'Enum_Parameter', critical: 'bool', length: 'int', id: @info_final class OverlayIDParameter(Parameter): - """Data mode HIP ``OVERLAY_ID`` parameter.""" + """Data model for HIP ``OVERLAY_ID`` parameter.""" #: Identifier. id: 'int' @@ -665,7 +672,7 @@ def __init__(self, type: 'Enum_Parameter', critical: 'bool', length: 'int', id: @info_final class Flags(Data): - """Data model for flags in HIP ``HIP_PARAMETER_FLAGS`` parameter.""" + """Data model for the flags in HIP ``ROUTE_DST`` and ``ROUTE_VIA`` parameters.""" #: Symmetric flag. symmetric: 'bool' diff --git a/pcapkit/protocols/data/internet/ipv4.py b/pcapkit/protocols/data/internet/ipv4.py index 2874afac34..e628a39b5d 100644 --- a/pcapkit/protocols/data/internet/ipv4.py +++ b/pcapkit/protocols/data/internet/ipv4.py @@ -50,7 +50,8 @@ class ToSField(Data): """Data model for IPv4 ToS fields. Important: - Due to the reserved keyword conflict, please use :meth:`from_dict` + Due to the reserved keyword conflict, please use + :meth:`~pcapkit.corekit.infoclass.Info.from_dict` to create an instance of this data model. """ @@ -323,7 +324,8 @@ class TROption(Option): """Data model for IPv4 Traceroute (``TR``) option. Important: - Due to the reserved keyword conflict, please use :meth:`from_dict` + Due to the reserved keyword conflict, please use + :meth:`~pcapkit.corekit.infoclass.Info.from_dict` to create an instance of this data model. """ diff --git a/pcapkit/protocols/data/internet/ipv6.py b/pcapkit/protocols/data/internet/ipv6.py index 3c7062b9fe..4181e9e13b 100644 --- a/pcapkit/protocols/data/internet/ipv6.py +++ b/pcapkit/protocols/data/internet/ipv6.py @@ -27,7 +27,8 @@ class IPv6(Protocol): """Data model for Internet Protocol version 6. Important: - Due to the reserved keyword conflict, please use :meth:`from_dict` + Due to the reserved keyword conflict, please use + :meth:`~pcapkit.corekit.infoclass.Info.from_dict` to create an instance of this data model. """ diff --git a/pcapkit/protocols/internet/hip.py b/pcapkit/protocols/internet/hip.py index 4b1f3323d1..1d3d8811c3 100644 --- a/pcapkit/protocols/internet/hip.py +++ b/pcapkit/protocols/internet/hip.py @@ -882,7 +882,7 @@ def _read_param_unassigned(self, schema: 'Schema_UnassignedParameter', *, versio +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -919,7 +919,7 @@ def _read_param_esp_info(self, schema: 'Schema_ESPInfoParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -964,7 +964,7 @@ def _read_param_r1_counter(self, schema: 'Schema_R1CounterParameter', *, version +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -972,7 +972,8 @@ def _read_param_r1_counter(self, schema: 'Schema_R1CounterParameter', *, version Parsed parameter data. Raises: - ProtocolError: If ``schema.len`` is **NOT** ``12`` or the parameter is **NOT** used in HIPv1. + ProtocolError: If ``schema.len`` is **NOT** ``12``, or the parameter + is the HIPv1-only code ``128`` in a packet of another version. """ if schema.len != 12: @@ -1025,7 +1026,7 @@ def _read_param_locator_set(self, schema: 'Schema_LocatorSetParameter', *, versi +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1117,7 +1118,7 @@ def _read_param_puzzle(self, schema: 'Schema_PuzzleParameter', *, version: 'int' +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1199,7 +1200,7 @@ def _read_param_solution(self, schema: 'Schema_SolutionParameter', *, version: ' +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1267,7 +1268,7 @@ def _read_param_seq(self, schema: 'Schema_SEQParameter', *, version: 'int', # p +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1310,7 +1311,7 @@ def _read_param_ack(self, schema: 'Schema_ACKParameter', *, version: 'int', # p +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1351,7 +1352,7 @@ def _read_param_dh_group_list(self, schema: 'Schema_DHGroupListParameter', *, ve +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1394,7 +1395,7 @@ def _read_param_diffie_hellman(self, schema: 'Schema_DiffieHellmanParameter', *, +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1431,7 +1432,7 @@ def _read_param_hip_transform(self, schema: 'Schema_HIPTransformParameter', *, v +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1439,7 +1440,8 @@ def _read_param_hip_transform(self, schema: 'Schema_HIPTransformParameter', *, v Parsed parameter data. Raises: - ProtocolError: The parameter is **ONLY** supported in HIPv1. + ProtocolError: If the parameter is used in a version other than + HIPv1, or ``schema.len`` is **NOT** a ``2`` modulo. """ if version != 1: @@ -1474,7 +1476,7 @@ def _read_param_hip_cipher(self, schema: 'Schema_HIPCipherParameter', *, version +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1531,7 +1533,7 @@ def _read_param_nat_traversal_mode(self, schema: 'Schema_NATTraversalModeParamet +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1571,7 +1573,7 @@ def _read_param_transaction_pacing(self, schema: 'Schema_TransactionPacingParame +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1619,7 +1621,7 @@ def _read_param_encrypted(self, schema: 'Schema_EncryptedParameter', *, version: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1661,7 +1663,7 @@ def _read_param_host_id(self, schema: 'Schema_HostIDParameter', *, version: 'int +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1722,7 +1724,7 @@ def _read_param_hit_suite_list(self, schema: 'Schema_HITSuiteListParameter', *, +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1765,7 +1767,7 @@ def _read_param_cert(self, schema: 'Schema_CertParameter', *, version: 'int', # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1807,7 +1809,7 @@ def _read_param_notification(self, schema: 'Schema_NotificationParameter', *, ve +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1842,7 +1844,7 @@ def _read_param_echo_request_signed(self, schema: 'Schema_EchoRequestSignedParam +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1879,7 +1881,7 @@ def _read_param_reg_info(self, schema: 'Schema_RegInfoParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1920,7 +1922,7 @@ def _read_param_reg_request(self, schema: 'Schema_RegRequestParameter', *, versi +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1958,7 +1960,7 @@ def _read_param_reg_response(self, schema: 'Schema_RegResponseParameter', *, ver +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -1996,7 +1998,7 @@ def _read_param_reg_failed(self, schema: 'Schema_RegFailedParameter', *, version +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2035,7 +2037,7 @@ def _read_param_reg_from(self, schema: 'Schema_RegFromParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2077,7 +2079,7 @@ def _read_param_echo_response_signed(self, schema: 'Schema_EchoResponseSignedPar +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2112,7 +2114,7 @@ def _read_param_transport_format_list(self, schema: 'Schema_TransportFormatListP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2158,7 +2160,7 @@ def _read_param_esp_transform(self, schema: 'Schema_ESPTransformParameter', *, v +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2198,7 +2200,7 @@ def _read_param_seq_data(self, schema: 'Schema_SeqDataParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2238,7 +2240,7 @@ def _read_param_ack_data(self, schema: 'Schema_AckDataParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2284,7 +2286,7 @@ def _read_param_payload_mic(self, schema: 'Schema_PayloadMICParameter', *, versi +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2322,7 +2324,7 @@ def _read_param_transaction_id(self, schema: 'Schema_TransactionIDParameter', *, +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2357,7 +2359,7 @@ def _read_param_overlay_id(self, schema: 'Schema_OverlayIDParameter', *, version +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2403,7 +2405,7 @@ def _read_param_route_dst(self, schema: 'Schema_RouteDstParameter', *, version: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2452,7 +2454,7 @@ def _read_param_hip_transport_mode(self, schema: 'Schema_HIPTransportModeParamet +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2496,7 +2498,7 @@ def _read_param_hip_mac(self, schema: 'Schema_HIPMACParameter', *, version: 'int +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2533,7 +2535,7 @@ def _read_param_hip_mac_2(self, schema: 'Schema_HIPMAC2Parameter', *, version: ' +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2568,7 +2570,7 @@ def _read_param_hip_signature_2(self, schema: 'Schema_HIPSignature2Parameter', * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2604,7 +2606,7 @@ def _read_param_hip_signature(self, schema: 'Schema_HIPSignatureParameter', *, v +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2638,7 +2640,7 @@ def _read_param_echo_request_unsigned(self, schema: 'Schema_EchoRequestUnsignedP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2671,7 +2673,7 @@ def _read_param_echo_response_unsigned(self, schema: 'Schema_EchoResponseUnsigne +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2709,7 +2711,7 @@ def _read_param_relay_from(self, schema: 'Schema_RelayFromParameter', *, version +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2759,7 +2761,7 @@ def _read_param_relay_to(self, schema: 'Schema_RelayToParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2791,7 +2793,7 @@ def _read_param_overlay_ttl(self, schema: 'Schema_OverlayTTLParameter', *, versi options: 'Parameter') -> 'Data_OverlayTTLParameter': # pylint: disable=unused-argument """Read HIP ``OVERLAY_TTL`` parameter. - Structure of HIP ``OVERLAY_TTL`` parameter [:rfc:`6078`]: + Structure of HIP ``OVERLAY_TTL`` parameter [:rfc:`6079`]: .. code-block:: text @@ -2804,7 +2806,7 @@ def _read_param_overlay_ttl(self, schema: 'Schema_OverlayTTLParameter', *, versi +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2857,7 +2859,7 @@ def _read_param_route_via(self, schema: 'Schema_RouteViaParameter', *, version: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2905,7 +2907,7 @@ def _read_param_from(self, schema: 'Schema_FromParameter', *, version: 'int', # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2946,7 +2948,7 @@ def _read_param_rvs_hmac(self, schema: 'Schema_RVSHMACParameter', *, version: 'i +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -2966,7 +2968,7 @@ def _read_param_via_rvs(self, schema: 'Schema_ViaRVSParameter', *, version: 'int options: 'Parameter') -> 'Data_ViaRVSParameter': # pylint: disable=unused-argument """Read HIP ``VIA_RVS`` parameter. - Structure of HIP ``VIA_RVS`` parameter [:rfc:`6028`]: + Structure of HIP ``VIA_RVS`` parameter [:rfc:`8004`]: .. code-block:: text @@ -2990,7 +2992,7 @@ def _read_param_via_rvs(self, schema: 'Schema_ViaRVSParameter', *, version: 'int +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -3031,7 +3033,7 @@ def _read_param_relay_hmac(self, schema: 'Schema_RelayHMACParameter', version: ' +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Args: - schema: parsed parameter schama + schema: parsed parameter schema version: HIP protocol version options: parsed HIP parameters @@ -3196,6 +3198,10 @@ def _make_param_r1_counter(self, code: 'Enum_Parameter', param: 'Optional[Data_R Returns: HIP parameter schema. + Raises: + ProtocolError: If ``code`` is the HIPv1-only ``128`` and ``version`` + is **NOT** ``1``. + """ if code == Enum_Parameter.R1_Counter and version != 1: raise ProtocolError(f'HIPv{version}: [ParamNo {code}] invalid parameter') @@ -3490,8 +3496,10 @@ def _make_param_puzzle(self, code: 'Enum_Parameter', param: 'Optional[Data_Puzzl HIP parameter schema. Raises: - ProtocolError: If ``lifetime_exponent`` does not fit one octet, or - ``lifetime`` cannot be encoded; see :meth:`_make_puzzle_lifetime`. + ProtocolError: If ``lifetime_exponent`` does not fit one octet, + ``lifetime`` cannot be encoded, or the width of ``Random #I`` is + invalid; see ``_make_puzzle_lifetime`` and + ``_make_puzzle_field_width``. """ if param is not None: @@ -3556,6 +3564,10 @@ def _make_param_solution(self, code: 'Enum_Parameter', param: 'Optional[Data_Sol Returns: HIP parameter schema. + Raises: + ProtocolError: If the width of the two fields is invalid; see + ``_make_puzzle_field_width``. + """ if param is not None: index = param.index @@ -3605,6 +3617,7 @@ def _make_param_seq(self, code: 'Enum_Parameter', param: 'Optional[Data_SEQParam param: parameter data version: HIP protocol version update_id: update ID + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -3630,6 +3643,7 @@ def _make_param_ack(self, code: 'Enum_Parameter', param: 'Optional[Data_ACKParam param: parameter data version: HIP protocol version update_id: list of update ID + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -3917,10 +3931,15 @@ def _make_param_encrypted(self, code: 'Enum_Parameter', param: 'Optional[Data_En data: encrypted data reserved: the four reserved octets, truncated or zero-filled to 4 octets + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. + Raises: + ProtocolError: If the cipher is ``AES-128-CBC`` or ``AES-256-CBC`` + and ``iv`` is missing or **NOT** 16 octets. + """ if param is not None: reserved = getattr(param, 'reserved', b'\x00\x00\x00\x00') @@ -4093,6 +4112,7 @@ def _make_param_hit_suite_list(self, code: 'Enum_Parameter', param: 'Optional[Da suite_default: default suite suite_namespace: suite namespace suite_reversed: reverse suite namespace + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -4368,6 +4388,7 @@ def _make_param_reg_response(self, code: 'Enum_Parameter', param: 'Optional[Data reg_response_default: default registration response reg_response_namespace: registration response namespace reg_response_reversed: reverse registration response namespace + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -4413,6 +4434,7 @@ def _make_param_reg_failed(self, code: 'Enum_Parameter', param: 'Optional[Data_R reg_failed_default: default registration failure reg_failed_namespace: registration failure namespace reg_failed_reversed: reverse registration failure namespace + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -4641,6 +4663,7 @@ def _make_param_ack_data(self, code: 'Enum_Parameter', param: 'Optional[Data_Ack param: parameter data version: HIP protocol version ack: ACK list + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -4777,6 +4800,7 @@ def _make_param_route_dst(self, code: 'Enum_Parameter', param: 'Optional[Data_Ro hit: list of HITs reserved: the two reserved octets, truncated or zero-filled to 2 octets + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -5014,6 +5038,7 @@ def _make_param_echo_response_unsigned(self, code: 'Enum_Parameter', param: 'Opt param: parameter data version: HIP protocol version opaque: opaque data + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -5052,6 +5077,7 @@ def _make_param_relay_from(self, code: 'Enum_Parameter', param: 'Optional[Data_R address: relay address reserved: the reserved octet, truncated or zero-filled to 1 octet + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. @@ -5176,6 +5202,7 @@ def _make_param_route_via(self, code: 'Enum_Parameter', param: 'Optional[Data_Ro hit: list of HITs reserved: the two reserved octets, truncated or zero-filled to 2 octets + **kwargs: arbitrary keyword arguments Returns: HIP parameter schema. diff --git a/pcapkit/protocols/internet/internet.py b/pcapkit/protocols/internet/internet.py index 934d9f73f4..835f183d2a 100644 --- a/pcapkit/protocols/internet/internet.py +++ b/pcapkit/protocols/internet/internet.py @@ -10,12 +10,6 @@ :class:`~pcapkit.protocols.internet.ipsec.IPsec`, :class:`~pcapkit.protocols.internet.ipv4.IPv4`, :class:`~pcapkit.protocols.internet.ipv6.IPv6`, :class:`~pcapkit.protocols.internet.ipx.IPX`, and etc. -.. versionremoved:: 1.5.0 - - ``pcapkit.protocols.internet.internet.EXTENSION_HEADER_LIMIT``, now - :data:`pcapkit.utilities.config.EXTENSION_HEADER_LIMIT`, set with - :envvar:`PCAPKIT_EXTENSION_HEADER_LIMIT` (:issue:`1726`). - """ import collections import contextvars @@ -97,7 +91,7 @@ class Internet(ProtocolBase[_PT, _ST], Generic[_PT, _ST]): # pylint: disable=ab .. 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 + ``data``, so that ``from_data(info).data`` rebuilds it exactly (:issue:`1446`). """ diff --git a/pcapkit/protocols/internet/ipv4.py b/pcapkit/protocols/internet/ipv4.py index 416986946f..47c439eac3 100644 --- a/pcapkit/protocols/internet/ipv4.py +++ b/pcapkit/protocols/internet/ipv4.py @@ -192,8 +192,10 @@ class IPv4(IP[Data_IPv4, Schema_IPv4], 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 + * A rebuild from + :meth:`~pcapkit.protocols.internet.internet.Internet.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 @@ -1367,7 +1369,7 @@ def _make_ipv4_options(self, options: 'list[Schema_Option | tuple[Enum_OptionNum octets for options. Args: - option: IPv4 options + options: IPv4 options padding: octets after the End of Option List Returns: @@ -1812,8 +1814,8 @@ def _make_opt_e_sec(self, kind: 'Enum_OptionNumber', option: 'Optional[Data_ESEC info: additional security information **kwargs: arbitrary keyword arguments - Returns: - Constructed option schema. + Returns: + Constructed option schema. """ if option is not None: diff --git a/pcapkit/protocols/internet/ipv6.py b/pcapkit/protocols/internet/ipv6.py index c292667747..ea3b09a73e 100644 --- a/pcapkit/protocols/internet/ipv6.py +++ b/pcapkit/protocols/internet/ipv6.py @@ -77,11 +77,14 @@ class IPv6(IP[Data_IPv6, Schema_IPv6], .. 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 + * A Shim6 header, which has no dedicated parser, and a header in + :attr:`__generic_ext_codes__` whose dedicated parser raises are parsed + by :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext`, so the + rest of the chain is still walked (:issue:`891`). + * A rebuild from + :meth:`~pcapkit.protocols.internet.internet.Internet.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 @@ -110,9 +113,10 @@ class IPv6(IP[Data_IPv6, Schema_IPv6], #: * :attr:`~pcapkit.const.ipv6.extension_header.ExtensionHeader.Shim6` #: has no dedicated parser (``pcapkit/protocols/internet/NotImplemented/shim6.py`` #: is a 0-byte placeholder), so there is no "own parser" for it to raise - #: from. It reaches :class:`IPv6_Ext` by *direct* registration (see the - #: bottom of :mod:`pcapkit.protocols.internet.ipv6_ext`), which already - #: produces exactly this class. + #: from. It reaches :class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext` + #: by *direct* registration (see the bottom of + #: :mod:`pcapkit.protocols.internet.ipv6_ext`), which already produces + #: exactly this class. #: * ``ESP`` *does* have a dedicated, registered parser #: (:class:`~pcapkit.protocols.internet.esp.ESP`). It is excluded #: because :rfc:`4303` places the real Next Header byte inside the diff --git a/pcapkit/protocols/internet/ipx.py b/pcapkit/protocols/internet/ipx.py index a602f6ff61..0a1cb5ac0d 100644 --- a/pcapkit/protocols/internet/ipx.py +++ b/pcapkit/protocols/internet/ipx.py @@ -54,7 +54,8 @@ class IPX(Internet[Data_IPX, Schema_IPX], .. versionchanged:: 1.5.0 - :meth:`from_data` rebuilds a parsed packet rather than raising + :meth:`~pcapkit.protocols.internet.internet.Internet.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` diff --git a/pcapkit/protocols/schema/internet/hip.py b/pcapkit/protocols/schema/internet/hip.py index 34c4e5a8cb..c7c5346fde 100644 --- a/pcapkit/protocols/schema/internet/hip.py +++ b/pcapkit/protocols/schema/internet/hip.py @@ -129,12 +129,15 @@ def locator_value_selector(pkt: 'dict[str, Any]') -> 'Field': pkt: Packet data. Returns: - * If ``kind`` is ``0`` and ``size`` is ``16``, + * If ``type`` is ``0`` and ``len`` is ``4``, i.e. a 16-octet locator, returns an :class:`~pcapkit.corekit.fields.ipaddress.IPv6AddressField` instance. - * If ``kind`` is ``1`` and ``size`` is ``20``, + * If ``type`` is ``1`` and ``len`` is ``5``, i.e. a 20-octet locator, returns a :class:`~pcapkit.corekit.fields.misc.SchemaField` wrapped :class:`~pcapkit.protocols.schema.internet.hip.LocatorData` instance. + Raises: + FieldValueError: For any other locator type and length. + """ if pkt['type'] == 0 and pkt['len'] == 4: return IPv6AddressField() @@ -162,6 +165,8 @@ def host_id_hi_selector(pkt: 'dict[str, Any]') -> 'Field': * If ``algorithm`` is ``13`` (EdDSA), returns a :class:`~pcapkit.corekit.fields.misc.SchemaField` wrapped :class:`~pcapkit.protocols.schema.internet.hip.EdDSACurveHostIdentity` instance. + * Otherwise, returns a :class:`~pcapkit.corekit.fields.strings.BytesField` + instance of ``hi_len`` octets. """ algo = pkt['algorithm'] @@ -281,9 +286,8 @@ def transport_format_list_len(pkt: 'dict[str, Any]') -> 'int': two octets -- the same width the base :class:`Parameter` class uses for its own ``type`` field, since a TF type *is* a HIP parameter type number -- which is why ``formats``' ``item_type`` is - ``EnumField(length=2, ...)``, matching :class:`HIPTransportModeParameter`'s - ``mode`` rather than the one-octet items of :func:`two_octet_prefix_list_len`'s - other two call sites. This function only answers how many *bytes* the + ``EnumField(length=2, ...)``, the width of the items at all three of + :func:`two_octet_prefix_list_len`'s call sites as well. This function only answers how many *bytes* the list occupies; getting that number right and the item width wrong (one octet) would still corrupt every non-empty list, just by reading twice as many entries as the wire holds instead of dropping octets. @@ -510,7 +514,7 @@ class Parameter(EnumSchema[Enum_Parameter]): @schema_final class UnassignedParameter(Parameter): - """Header schema for HIP unsigned parameters.""" + """Header schema for HIP unassigned parameters.""" #: Parameter value. value: 'bytes' = BytesField(length=lambda pkt: pkt['len']) @@ -557,7 +561,7 @@ class R1CounterParameter(Parameter, code=[Enum_Parameter.R1_Counter, two hand-written entries -- not a name-normalisation rule; ``R1_Counter`` and ``R1_COUNTER`` differ only in case, and each needs its own line -- mapping both codes to the same ``_read_param_r1_counter``, and - ``_make_param_r1_counter`` builds this class for 128. The schema lookup + ``_make_param_r1_counter`` builds this class for either code. The schema lookup this class's own ``code=`` feeds -- consulted on the parse path by :class:`~pcapkit.corekit.fields.collections.OptionField` -- would fall back to :class:`UnassignedParameter` for 128 if a single-code ``code=`` @@ -794,7 +798,7 @@ def __init__(self, type: 'Enum_Parameter', len: 'int', group: 'Enum_Group', pub_ @schema_final class HIPTransformParameter(Parameter, code=Enum_Parameter.HIP_TRANSFORM): - """Header schema for HIP ``TRANSFORM`` parameters.""" + """Header schema for HIP ``HIP_TRANSFORM`` parameters.""" #: Suite IDs. suites: 'list[Enum_Suite]' = ListField( @@ -810,7 +814,7 @@ def __init__(self, type: 'Enum_Parameter', len: 'int', suites: 'list[Enum_Suite] @schema_final class HIPCipherParameter(Parameter, code=Enum_Parameter.HIP_CIPHER): - """Header schema for HIP ``CIPHER`` parameters.""" + """Header schema for HIP ``HIP_CIPHER`` parameters.""" #: Cipher IDs. ciphers: 'list[Enum_Cipher]' = ListField( @@ -1266,7 +1270,7 @@ class PayloadMICParameter(Parameter, code=Enum_Parameter.PAYLOAD_MIC): #: Next header. next: 'Enum_TransType' = EnumField(length=1, namespace=Enum_TransType) - #: Reversed. + #: Reserved. reserved: 'bytes' = PaddingField(length=3) #: Payload data. payload: 'bytes' = BytesField(length=4) diff --git a/pcapkit/protocols/schema/internet/ipv4.py b/pcapkit/protocols/schema/internet/ipv4.py index e6502ffbb9..cdcd084278 100644 --- a/pcapkit/protocols/schema/internet/ipv4.py +++ b/pcapkit/protocols/schema/internet/ipv4.py @@ -220,8 +220,10 @@ def quick_start_data_selector(pkt: 'dict[str, Any]') -> 'Field': leftover octets are read as a further, fabricated option. """ - # NOTE: The enumeration admits ``0`` to ``8`` only, while the field is four - # bits wide; a function above ``8`` is just as unassigned. + # NOTE: The enumeration admits the whole four-bit range, ``0`` to ``15``, + # as an ``Unassigned`` member for every code but ``0`` and ``8``, and only + # those two have a schema registered. A value past four bits, which only a + # caller-built packet can carry, fails the lookup and is just as unassigned. try: func = Enum_QSFunction.get(pkt['flags']['func']) except EnumValueError: diff --git a/tests/test_docstring_contract.py b/tests/test_docstring_contract.py index d1fc37726f..fad63c0248 100644 --- a/tests/test_docstring_contract.py +++ b/tests/test_docstring_contract.py @@ -226,16 +226,12 @@ class Known(NamedTuple): # parameter is 'name', which is #546's item 2. The remaining 34 register_* # functions in that file were checked at the same time and none of them # carries the same defect, so there is nothing left to record here for it. - Known(Finding('pcapkit/protocols/internet/ipv4.py', - '_make_ipv4_options', 'option'), - "documents 'option' where the parameter is 'options'; ipv4.py is " - 'owned by another change'), Known(Finding('pcapkit/vendor/mh/binding_ack_flag.py', 'context', 'soup'), "documents 'soup: Parsed HTML source.' where the parameter is 'data' " "and holds CSV rows. Nothing was renamed here despite the " '``# pylint: disable=arguments-renamed`` pragma -- the parameter ' 'matches the base ``Vendor.context(self, data)`` in ' - 'pcapkit/vendor/default.py:288, which documents it as ' + 'pcapkit/vendor/default.py:417, which documents it as ' "'data: CSV data.'. The line was copy-pasted from a sibling whose " "process()/context() really does take 'soup', so both the name and " 'the description are wrong'), @@ -252,13 +248,10 @@ class Known(NamedTuple): "documents 'data' where the parameter is 'soup'"), ) -#: Swallowed section headers left unfixed, for the same ownership reason. -KNOWN_SWALLOWED = ( - Known(Finding('pcapkit/protocols/internet/ipv4.py', '_make_opt_e_sec', 'Returns'), - 'the ``Returns:`` header is indented into the ``Args:`` block, so ' - 'napoleon renders ``:param Returns:`` and drops the return ' - 'documentation; ipv4.py is owned by another change'), -) +#: Swallowed section headers excused from +#: :meth:`DocstringParameterTests.test_section_headers_are_not_swallowed`, in +#: the same form as :data:`KNOWN_DEFECTS`. None is excused. +KNOWN_SWALLOWED = () def _header(line: 'str') -> 'Optional[str]':