Skip to content

packet context is never forwarded as __packet__ to schema unpack #382

Description

@JarryShaw

Found while reviewing #378 (Copilot raised it there against three _import_next_layer sites). It is pre-existing on main, not introduced by that PR — filing separately so #378 stays scoped.

The gap

ProtocolBase._import_next_layer instantiates the next protocol with packet=packet:

next_ = protocol(file_, length, alias=proto, packet=packet,
                 layer=self._exlayer, protocol=self._exproto)

packet= reaches the protocol, but the schema layer reads its per-packet context from a separate special keyword, __packet__ (pcapkit/protocols/protocol.py:284,304 — packet = kwargs.get('__packet__', {})). Nothing bridges the two, so a schema's unpack/post_process always sees an empty packet dict, whatever the outer layer populated. The same shape appears in the Internet and IPv6 overrides of _import_next_layer.

Verified pre-existing: git show origin/main:pcapkit/protocols/protocol.py has the identical packet=packet call with no __packet__, before ESP existed.

Observable consequence

pcapkit/protocols/schema/internet/ipv6_route.py:157 is a real consumer — the RPL Source Route Header reconstructs its compressed addresses from the outer destination:

dst_val = cast('Optional[IPv6Address]', packet.get('dst'))
dst = dst_val.packed if dst_val is not None else None
...
if dst is None:      # degraded path: elided prefix octets cannot be restored

Because dst is never supplied, that branch is always taken and the compressed addresses are never fully reconstructed, regardless of what IPv6.read populated.

Caveat on reachability

I have not been able to demonstrate this end to end on a real capture, because the RPL and source-route paths in pcapkit/protocols/internet/ipv6_route.py currently reject well-formed headers for an unrelated reason (_read_data_type_rpl / _read_data_type_src compare the schema's raw Hdr Ext Len octet against octet counts) — so the degraded branch may be masked today by an earlier failure. The __packet__ gap is established by reading the call chain; the user-visible effect is inferred, and confirming it likely depends on fixing the type-dispatch bugs first.

What a fix would touch

_import_next_layer in pcapkit/protocols/protocol.py, plus the Internet and IPv6 overrides, to pass the packet dict through as __packet__ as well as packet=. Worth checking whether any schema currently relies on receiving an empty dict before changing it, and it needs a test that asserts a schema's post_process actually sees an outer-layer value.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions