Extension-Header Base Classes¶
Every IPv6 extension header in this package subclasses
IPv6_Ext. Some name a second base
as well, and which ones do is a ruling rather than an accident. The owner ruled, in
review of the rename that made IPv6_Ext the
shared base (#917), that a header usable only as an extension header inherits
IPv6_Ext and nothing else –
IPv6_Frag being the example – while one
that is usable as a standalone protocol in its own right inherits both
IPv6_Ext and
Internet (or
IPsec), as
ESP does.
The family:
Header |
Bases |
Classification |
|---|---|---|
extension-header only |
||
also standalone |
||
also standalone |
IPsec is itself an
Internet subclass, which is the
parenthetical IPsec alternative in the ruling:
naming it satisfies the convention, and it is the right second base for a header whose
standalone form is an IPsec one.
The IPv4-Payload Test¶
So each header is classified from its RFCs, on the owner’s instruction, and the test that decides is whether a primary source shows the header carried directly as an IPv4 payload:
AH– RFC 4302 Section 3.1.1, “In the context of IPv4, this calls for placing AH after the IP header”, with a before-and-after IPv4 diagram.ESP– RFC 4303 Section 3.1.1, the same sentence and the same diagram for ESP.HIP– RFC 7401 Appendix C.2, “IPv4 HIP Packet (I1 Packet)”, whose worked checksum is over an IPv4 header carryingNext Header: 139. RFC 7401 Section 5.1 also calls the HIP header “logically an IPv6 extension header”, so HIP is genuinely both.
MH is the instructive failure, because it
is a protocol in its own right and still does not qualify:
RFC 6275 Section 6.1.1 defines its checksum over a pseudo-header of “IPv6 header
fields” whose addresses are “the addresses that appear in the Source and
Destination Address fields in the IPv6 packet carrying the Mobility Header” – there
is no IPv4 variant of that computation – and the IPv4 equivalent function is not
protocol 135 at all, since RFC 5944 carries Mobile IPv4 over UDP port 434.
Shim6 (140) has the same shape and the same verdict; this package carries no parser
class for it, so nothing implements the classification, but a future one inherits
IPv6_Ext alone.
Important
Own-protocolhood on its own is not sufficient, and MH is the case that
settles it: the alternative reading – that a protocol in its own right qualifies
whether or not it can appear under IPv4 – was put to the owner explicitly in
review of #917 and not
taken, so MH and Shim6 stay extension-only. A header that is a protocol in its
own right but structurally cannot be an IPv4 payload names
IPv6_Ext alone.
Explicit Base Declarations¶
Name the second base explicitly, even where it is already in the MRO.
IPv6_Ext derives
Internet, so every extension header
reaches Internet transitively and an
__mro__ check cannot tell the two groups apart. The declaration is the only place the
classification exists, which is why tests/protocols/internet/test_ipv6_ext_unit.py
pins it against __bases__:
STANDALONE_MEMBERS = frozenset({'AH', 'ESP', 'HIP'})
Add a header to that set in the same change that adds its second base, and keep the
RFC ground in the #: comment beside it. The test walks
IPv6_Ext.__subclasses__() rather than a hard-coded list, so any further header is
held to the convention whether or not anyone remembers this page.
ESP’s Two Facts¶
Two facts about ESP coexist, and
mistaking one for a refutation of the other either drops ESP from the
extension-header contract or walks the chain past it.
It is an extension header. IANA’s IPv6 Extension Header Types registry lists
protocol number 50, and this package’s
ExtensionHeader agrees (ESP = 50).
RFC 8200 Section 4.5 appears to say otherwise – “the Encapsulating Security
Payload (ESP) is not considered an extension header” – but that sentence opens
“For this purpose,”, scoping it to the fragmentation discussion it sits in, and the
sentence after it lists ESP among “examples of upper-layer headers”. The library
follows the registry, on the owner’s ruling for
#895, which is why ESP
carries the same extension-mode contract as its siblings.
And it terminates the chain walk. RFC 4303 places ESP’s Next Header byte
inside the encrypted trailer, so with no key material there is nothing to continue
on: ESP’s own data model reports next as None, and
IPv6._decode_next_layer
ends the ordinary way one iteration later – not because ESP lacks a parser, which
it has, but because it cannot hand the walk a successor.
The full reasoning, including how ESP’s terminal case differs from 253/254’s, lives
with the code: see
IPv6._import_next_layer
and the module docstring of pcapkit.protocols.internet.ipv6_ext.protocol.