Summary
Two more HIP list fields size their entries at one octet where the RFC
specifies 16 bits, so a single-entry list round-trips with a spurious extra
entry, the packed length disagrees with the declared Length, and parsing
through the public API fails outright.
This is the same defect class as #463, at two sites #463 did not cover. PR #466
fixed it for TransportFormatListParameter; these two remain.
Sites
pcapkit/protocols/schema/internet/hip.py:567-570 — NATTraversalModeParameter.modes,
item_type=EnumField(length=1, namespace=Enum_NATTraversal). :rfc:5770 §5.4
specifies a 16-bit Mode ID.
pcapkit/protocols/schema/internet/hip.py:939-942 — ESPTransformParameter.suites,
item_type=EnumField(length=1, namespace=Enum_ESPTransformSuite). :rfc:7402
§5.1.2 specifies a 16-bit Suite ID.
HIPTransportModeParameter.mode in the same file already uses length=2, so the
correct shape is established locally.
Reproduction
Measured on fa128959e, through the public makers. Byte-identical on PR #466's
branch, so pre-existing and not introduced by that PR, which only changed the
length= callback reference at these two sites:
proto = object.__new__(HIP)
s = proto._make_param_nat_traversal_mode(Parameter.NAT_TRAVERSAL_MODE, version=2, modes=[1])
s.pack() # 0260000400000100000000 -- 11 octets, declared len=4
NATTraversalModeParameter.unpack(s.pack()).modes # [1, 0] -- want [1]
s = proto._make_param_esp_transform(Parameter.ESP_TRANSFORM, version=2, suites=[1])
s.pack() # 0fff000400000100000000 -- 11 octets, declared len=4
ESPTransformParameter.unpack(s.pack()).suites # [1, 0] -- want [1]
So a one-element list comes back with a spurious second element.
Through the full HIP() parser it is worse than a wrong value — it reports
AttributeError: 'NATTraversalModeParameter' object has no attribute 'modes',
an outright parse failure.
Mechanism
The same three-way disagreement #466 documented for TRANSPORT_FORMAT_LIST: the
maker computes len on a two-octet-per-entry assumption (2 for the reserved
field plus 2 * count, hence len=4 for one entry), while item_type packs one
octet per entry, and the length callback then reads len - 2 octets as that many
one-octet items — twice as many as the wire holds.
Why the existing tests miss it
They assert against the schema object's Python attribute without packing and
unpacking. That is the same blind spot #466's history identifies as having let the
TransportFormatListParameter bug survive: a suite total cannot distinguish a
correct field from one whose declared length and item width are mutually
inconsistent, because nothing ever round-trips it.
Suggested direction
item_type=EnumField(length=2, ...) at both sites, matching
HIPTransportModeParameter.mode, then a round-trip test through the public
maker — not a hand-built schema with a self-consistent len the maker would
never produce — covering one, two and three entries. Check whether the generated
options-internet.pcap capture moves, and whether
EXPECTED_FAILURES['hip-parameter/NAT_TRAVERSAL_MODE'] and
['hip-parameter/ESP_TRANSFORM'] change shape; both are currently in the
sixteen-entry RECONSTRUCT: unsupported type <class 'tuple'> group.
Provenance
Surfaced by the review of #466 and verified independently on both trees before
filing. Deliberately not folded into #466, which was already at a
GOOD TO MERGE verdict for the TRANSPORT_FORMAT_LIST half.
Summary
Two more HIP list fields size their entries at one octet where the RFC
specifies 16 bits, so a single-entry list round-trips with a spurious extra
entry, the packed length disagrees with the declared
Length, and parsingthrough the public API fails outright.
This is the same defect class as #463, at two sites #463 did not cover. PR #466
fixed it for
TransportFormatListParameter; these two remain.Sites
pcapkit/protocols/schema/internet/hip.py:567-570—NATTraversalModeParameter.modes,item_type=EnumField(length=1, namespace=Enum_NATTraversal). :rfc:5770§5.4specifies a 16-bit Mode ID.
pcapkit/protocols/schema/internet/hip.py:939-942—ESPTransformParameter.suites,item_type=EnumField(length=1, namespace=Enum_ESPTransformSuite). :rfc:7402§5.1.2 specifies a 16-bit Suite ID.
HIPTransportModeParameter.modein the same file already useslength=2, so thecorrect shape is established locally.
Reproduction
Measured on
fa128959e, through the public makers. Byte-identical on PR #466'sbranch, so pre-existing and not introduced by that PR, which only changed the
length=callback reference at these two sites:So a one-element list comes back with a spurious second element.
Through the full
HIP()parser it is worse than a wrong value — it reportsAttributeError: 'NATTraversalModeParameter' object has no attribute 'modes',an outright parse failure.
Mechanism
The same three-way disagreement #466 documented for
TRANSPORT_FORMAT_LIST: themaker computes
lenon a two-octet-per-entry assumption (2for the reservedfield plus
2 * count, hencelen=4for one entry), whileitem_typepacks oneoctet per entry, and the length callback then reads
len - 2octets as that manyone-octet items — twice as many as the wire holds.
Why the existing tests miss it
They assert against the schema object's Python attribute without packing and
unpacking. That is the same blind spot #466's history identifies as having let the
TransportFormatListParameterbug survive: a suite total cannot distinguish acorrect field from one whose declared length and item width are mutually
inconsistent, because nothing ever round-trips it.
Suggested direction
item_type=EnumField(length=2, ...)at both sites, matchingHIPTransportModeParameter.mode, then a round-trip test through the publicmaker — not a hand-built schema with a self-consistent
lenthe maker wouldnever produce — covering one, two and three entries. Check whether the generated
options-internet.pcapcapture moves, and whetherEXPECTED_FAILURES['hip-parameter/NAT_TRAVERSAL_MODE']and['hip-parameter/ESP_TRANSFORM']change shape; both are currently in thesixteen-entry
RECONSTRUCT: unsupported type <class 'tuple'>group.Provenance
Surfaced by the review of #466 and verified independently on both trees before
filing. Deliberately not folded into #466, which was already at a
GOOD TO MERGEverdict for theTRANSPORT_FORMAT_LISThalf.