You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
IPv6_Ext family is missing the id() sibling-dispatch trick #2462
Every other versioned/shared protocol family on main implements the id() classmethod convention: the abstract family base returns a tuple of ALL sibling names for the protocol selector, and each concrete subclass overrides its own id() to narrow to just its own name(s) (with # type: ignore[override]). Confirmed present on:
pcapkit/protocols/internet/ipv6_ext.py's IPv6_Ext has no id() at all, and none of its concrete siblings (HOPOPT, IPv6_Frag, IPv6_Opts, IPv6_Route, MH) override id() either. (AH/ESP already have their own id() via IPsec, since they multiply-inherit both — leave those alone.)
Proposed fix
IPv6_Ext.id() returns the full family tuple, using each sibling's actual alias string (not necessarily the Python class name — IPv6_Frag.alias is 'IPv6-Frag' with a hyphen, not 'IPv6_Frag'): something like ('HOPOPT', 'IPv6-Route', 'IPv6-Opts', 'IPv6-Frag', 'MH', 'AH', 'ESP').
HOPOPT.id(), IPv6_Frag.id(), IPv6_Opts.id(), IPv6_Route.id(), MH.id() each narrow to their own alias name, matching the AH/ESP/C_Tag/S_Tag pattern.
A question I should have asked instead of assuming. "Take the proposal" above could mean either of two opposite things:
(a) This issue's own Proposed fix.IPv6_Ext.id() returns the family tuple ('HOPOPT', 'IPv6-Route', 'IPv6-Opts', 'IPv6-Frag', 'MH', 'AH', 'ESP'), and each sibling narrows to itself.
(b) The recommendation posted on fix(protocols): compose IPv6_Ext.id() from its direct concrete members #2464. No family tuple: IPv6_Ext is a concrete fallback parser (it is what IPv6 substitutes when a dedicated header parser fails, and it parses Shim6 directly), so not every IPv6_Ext instance really is one of those seven.
#2464 implemented (b), and I treated your reply as approving it. I shouldn't have.
My recommendation is (b), done by deleting IPv6_Ext.id() outright so it inherits the default (cls.__name__,). Under (a), selecting 'HOPOPT' would match a fallback-parsed Shim6 header. Hard-coding ('IPv6_Ext',), as #2464 does now, makes every future subclass without its own id() report as the fallback parser. Leaving it unoverridden gives each class its own name and needs no maintenance.
i think we'd still do (a). IPv6-Ext is an abstract name, so it should be a compose name for all sub protocols. Once we implement Shim6, the argument will no longer stand.
Taking (a): IPv6_Ext.id() composes its direct concrete sub-protocols, and each one narrows to itself. Redoing #2464 to match.
One caveat that outlives Shim6: IPv6 also substitutes IPv6_Ext when a dedicated parser fails, so a malformed HOPOPT parsed that way will match every sibling name.
Activity
JarryShaw commentedon Oct 30, 2026
Yes, take the proposal
JarryShaw commentedon Oct 30, 2026
Already dispatched this exact fix (drop the family-wide tuple, self-only narrowing on all 6 siblings) before this landed — in progress on PR #2464.
fix(protocols): add id() sibling-dispatch to the IPv6 extension heade…
JarryShaw commentedon Oct 30, 2026
A question I should have asked instead of assuming. "Take the proposal" above could mean either of two opposite things:
IPv6_Ext.id()returns the family tuple('HOPOPT', 'IPv6-Route', 'IPv6-Opts', 'IPv6-Frag', 'MH', 'AH', 'ESP'), and each sibling narrows to itself.IPv6_Extis a concrete fallback parser (it is whatIPv6substitutes when a dedicated header parser fails, and it parses Shim6 directly), so not everyIPv6_Extinstance really is one of those seven.#2464 implemented (b), and I treated your reply as approving it. I shouldn't have.
My recommendation is (b), done by deleting
IPv6_Ext.id()outright so it inherits the default(cls.__name__,). Under (a), selecting'HOPOPT'would match a fallback-parsed Shim6 header. Hard-coding('IPv6_Ext',), as #2464 does now, makes every future subclass without its ownid()report as the fallback parser. Leaving it unoverridden gives each class its own name and needs no maintenance.Which one? #2464's fix round waits on this.
JarryShaw commentedon Oct 30, 2026
i think we'd still do (a).
IPv6-Extis an abstract name, so it should be a compose name for all sub protocols. Once we implementShim6, the argument will no longer stand.JarryShaw commentedon Oct 30, 2026
Taking (a):
IPv6_Ext.id()composes its direct concrete sub-protocols, and each one narrows to itself. Redoing #2464 to match.One caveat that outlives
Shim6:IPv6also substitutesIPv6_Extwhen a dedicated parser fails, so a malformed HOPOPT parsed that way will match every sibling name.JarryShaw commentedon Oct 30, 2026
The caveat above is moot: per RFC 8200, a malformed known header will parse as
Raw(#2477).fix(protocols): compose IPv6_Ext.id() from its direct concrete members (
fix(protocols): compose IPv6_Ext.id() from its direct concrete members (
fix(protocols): compose IPv6_Ext.id() from its direct concrete members (