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 as it stands:
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 the census is read out of the specifications, on the owner’s instruction: work
through the RFCs to establish, for each defined IPv6 extension header, whether it is
extension-header-only or a standalone protocol as well, and decide from that whether it
inherits IPv6_Ext alone or names additional bases.
And the limb 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.
The Retired IPv6_GenericExt Name¶
The class arrived as IPv6_GenericExt, a fallback parser for an unrecognised
extension header (#891), and
#917 merged that role with
the shared-base role into one class under the shorter name. No compatibility alias
was left behind, and that was deliberate. The owner ruled that the
IPv6_GenericExt name goes for good: it was an intermediate state, and it was never
released.
What makes that safe rather than merely decided: the old name existed on main from
b3551cb63 to 93cf940b3, under four hours on one day, and no release tag falls
between the two commits – git tag --contains names the same tags for both – so it
appears in no release and the break has no callers to inconvenience. Do not
reintroduce it as an alias, and do not cite it as a former public name.
ESP’s Two Facts¶
Two facts about ESP coexist, and each is
routinely mistaken for a refutation of the other.
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. So ESP is absent from
IPv6.__generic_ext_codes__
– not because it 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, is
written where the code is and is deliberately not restated at length here: see the
#: comment on
IPv6.__generic_ext_codes__
(pcapkit/protocols/internet/ipv6.py) and the module docstring of
pcapkit.protocols.internet.ipv6_ext.
Caution
The two facts have to be kept apart when reading any of this. “ESP is not an extension header” (wrong, and RFC 8200 Section 4.5 quoted out of scope) is a different claim from “ESP cannot be walked past” (right, and about RFC 4303’s wire format). Collapsing them is how ESP ends up either dropped from the extension-header contract or wrongly added to the generic-dispatch set.