Repository navigation
feat(protocols)!: verify and compute one's-complement checksums (#2470) - #2543
Conversation
Shared pieces of the one's-complement checksum work (#2470, #2472-#2475): - utilities.config: CHECKSUM_VERIFY (PCAPKIT_CHECKSUM_VERIFY, off) and CHECKSUM_COMPUTE (PCAPKIT_CHECKSUM_COMPUTE, on), read with read_flag - protocols.misc.checksum.checksum: ChecksumStatus, the RFC 1071 sum, and helpers to compute and verify a checksum over an optional pseudo-header; a payload being rebuilt does not warn a second time - IPv4 and IPv6 verify their upper layer's pseudo-header checksum once parsed, and compute it for a payload whose make() left it pending, unless the IPv4 packet is a fragment - docs: the flags on the config page, the module on the checksum page, and the rulings in pep.rst
- IPv4.read verifies the header checksum (RFC 791 section 3.1) under CHECKSUM_VERIFY and records checksum_status; a wrong one warns, a zero one (header checksum offload) is NOT_COMPUTED - IPv4.make takes checksum=None by default and computes it over the header under CHECKSUM_COMPUTE; a given checksum is written as given, so a from_data rebuild stays byte-exact
- the enclosing IPv4 or IPv6 layer verifies the checksum over its pseudo-header (RFC 793 section 3.1) under CHECKSUM_VERIFY, recording checksum_status on the segment; a zero one or the pseudo-header's sum alone (checksum offload) is NOT_COMPUTED - TCP.make takes checksum=None by default and a pseudo keyword; it computes the checksum over pseudo, or leaves it to the IP layer the segment is the payload of, under CHECKSUM_COMPUTE
- the enclosing IPv4 or IPv6 layer verifies the checksum over its pseudo-header and the datagram the Length field gives (RFC 768) under CHECKSUM_VERIFY; a zero one is NOT_COMPUTED over IPv4 but INVALID over IPv6 (RFC 8200 section 8.1), and the pseudo-header's sum alone (checksum offload) is NOT_COMPUTED - UDP.make takes checksum=None by default and a pseudo keyword, computing the checksum as TCP.make does; a computed zero is sent as all ones
- OSPF.read verifies the OSPFv2 checksum over the packet but its Authentication field (RFC 2328 appendix A.3.1) under CHECKSUM_VERIFY and records checksum_status; under cryptographic authentication, where the field is unused (appendix D.4.3), it is NOT_COMPUTED - OSPF.make takes checksum=None by default and computes it the same way under CHECKSUM_COMPUTE, leaving it zero under cryptographic authentication; other versions are neither verified nor computed
) - ICMPv4.read verifies the checksum over the message (RFC 792) under CHECKSUM_VERIFY and records checksum_status; ICMPv4.make computes one it is not given under CHECKSUM_COMPUTE - the enclosing IPv6 layer verifies the ICMPv6 checksum over its pseudo-header (RFC 4443 section 2.3), past any extension headers - ICMPv6.make takes a pseudo keyword and computes the checksum as TCP.make does, or leaves it to the IPv6 layer the message is the payload of - the data models no longer say the checksum is never verified
- ICMPv4 verified a first IPv4 fragment over the fragment alone and recorded INVALID with a ProtocolWarning; IPv4 and IPv6 now parse a fragment's payload under checksum.fragment_payload(), and ICMPv4 records NO_PSEUDO_HEADER there, as TCP, UDP and ICMPv6 do. - ChecksumStatus.NO_PSEUDO_HEADER's doc names the paths that produce it, and no longer an upper layer behind ESP. - tests/project RFC-constant sweep: list OSPF's Authentication offset 16 and the RFC 1071 word mask and carry shift as unrelated values. - Drop counted and stale wording from the checksum docs, and a Sphinx role from a plain comment in ospf.py; pep.rst records the fragment ruling.
…eudo (#2513) - IP_Pseudo._source and _destination tested only the header after the fixed one for the Destination Options or Routing header the walk stopped on, so one past a valid header lost its Home Address or final destination with no error. Both now ask the new _walk, which _upper shares, where the walk stopped, at any depth. - _upper raises one error for an unparsed header, naming the protocol and upper_length it needs, instead of "give src" or "give dst". - Tests cover a malformed header past the first one, _upper with src or dst given, and the header-limit case, whose 33rd header now raises from _source.
|
Cross-review (Sonnet) at
The |
- verify_checksum warned with ProtocolWarning, so a filter could not silence mismatches without silencing every protocol warning. It now warns with ChecksumWarning, a ProtocolWarning subclass, so the IPv4 header, TCP, UDP, ICMP, ICMPv6 and OSPFv2 mismatches can be filtered on their own, and existing ProtocolWarning filters still match them. - ChecksumWarning is exported from pcapkit.utilities.warnings and documented beside ProtocolWarning; pep.rst, the checksum docs and CHECKSUM_VERIFY name it. - Tests re-pin each protocol's mismatch to ChecksumWarning and pin the subclass and the filters: ignoring ChecksumWarning keeps other ProtocolWarnings, and a ProtocolWarning filter still catches a mismatch.
|
Coverage: 93.98% (unit tier, Python 3.15,
Per-file detail: the |
|
Pushed
|
|
protocols.misc.checksum.checksum should go to foundation or corekit. And its module name should be clear that it's for internet protocols specifically, not a generic checksum name. |
|
Paraphrased: the checksum helpers leave |
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseconst— regenerates constant or registry tables, members keeping their numeric valuesDescription of your pull request and other information
Closes #2470, #2472, #2473, #2474, #2475 and #2513.
PCAPKIT_CHECKSUM_VERIFY(off) andPCAPKIT_CHECKSUM_COMPUTE(on), overridable per call. Each protocol records aChecksumStatus, shaped like ESP's status, and warns on a mismatch. The pseudo-header comes fromIP_Pseudo.NO_PSEUDO_HEADERwithout warning. The four offload shapes recordNOT_COMPUTED, as documented in pep.rst.make()now computes checksums by default, so constructed bytes change.IP_Pseudodetects an unparsed Destination Options or Routing header at any depth.ChecksumWarning(ProtocolWarning), lands as a commit here.