Skip to content

HIPv1 R1_Counter (128) parses as UnassignedParameter: R1CounterParameter registers code=129 only #690

Description

@JarryShaw

R1CounterParameter in pcapkit/protocols/schema/internet/hip.py is declared

class R1CounterParameter(Parameter, code=Enum_Parameter.R1_COUNTER):

i.e. for code 129 only. The HIP parameter registry that _read_hip_param consults is
keyed on that code=, so code 128 — R1_Counter, the HIPv1 spelling of the same
parameter — resolves to Parameter.__default__, which is UnassignedParameter. The
reader is then handed a schema with a value: bytes and no counter, and fails with

AttributeError: 'UnassignedParameter' object has no attribute 'counter'

The asymmetry is that the method dispatch does not have the problem. _read_param_* and
_make_param_* are found by enumeration member name, and pcapkit/protocols/internet/hip.py
maps both codes to the same handler:

Enum_Parameter.R1_Counter:             'r1_counter',              # [RFC 5201] 128, v1 only
Enum_Parameter.R1_COUNTER:             'r1_counter',              # [RFC 7401] 129

So code 128 constructs correctly — _make_param_r1_counter builds a real
R1CounterParameter, and _read_param_r1_counter even guards it, raising for
schema.type == 128 and version != 1. It is only the parse direction that cannot find the
schema.

Measured

CPython 3.14.7, editable finder stripped via getattr(f, '__module__', ''),
pcapkit.__file__ asserted to the worktree before any other import. On the tree with #672
applied, so the width is already correct and this is the only defect left in the parameter:

R1_COUNTER counter=0xaabbccdd    OK  packet=56 octets, 1 param(s), counter=0xaabbccdd, reported length=16
R1_Counter counter=0xaabbccdd    FAILED: AttributeError: 'UnassignedParameter' object has no attribute 'counter'

Same failure at one copy and at two, so the HIP_COPIES pair never routed around it.

Consequence

A HIPv1 R1 packet read off the wire loses its R1 generation counter, and pcapkit raises
rather than degrading. RFC 5201 §5.2.3 gives code 128 the same 4 + 8 layout RFC 7401
§5.2.3 gives 129, so the two are the same parameter under two numbers and one schema class
should serve both.

Suggested fix

Register the class for both codes. EnumSchema's code= takes a single member, so this
wants either a second registration for 128 against the same class or a widening of
code= to accept several — whichever the schema metaclass supports more honestly. Worth
checking whether any other parameter in the module has the same v1/v2 code pair and the
same gap.

tests/protocols/test_option_roundtrip_unit.py records this today as
hip-parameter/R1_Counter, Gap('PARSE', "no attribute 'counter'", ...); fixing it means
deleting that entry, which the table's own note asks for rather than leaving it behind.

Found while fixing #672. #672 widened the counter field to the 8 octets RFC 7401 §5.2.3
requires and deliberately did not touch this, since it is a registry-keying defect rather
than a width one and the R1_Counter expected-failure entry is unchanged by it. It is also
the sole remaining blocker to the tally in #689.

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