Skip to content

feat(link): split radiotap's mixed bitmaps into value subfields (#2647) - #2696

Merged
JarryShaw merged 1 commit into
mainfrom
feat/2647-radiotap-mixed-bitmaps
Nov 2, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
feat/2647-radiotap-mixed-bitmaps

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • feat — adds a feature

Description of your pull request and other information

The owner asked on #2576 for radiotap's mixed bitmaps to be decoded properly, in their final shape for 1.6.0. MCS flags, HE data1/data2, HE-MU flags1/flags2 and U-SIG common each decode into a typed data model: integer value subfields plus a known member.

  • New registries: HEData1Known, HEData2Known, HEMUFlags1Known, HEMUFlags2Known and USIGCommonKnown. They are crawled through the shared radiotap flag template, which gains a VALUES tuple so value rows stay subfields. Names come from Linux ieee80211_radiotap.h. Undefined bits are kept. MCS flags needs no registry, since its known bits are MCSKnown.
  • New field: BitmapField in pcapkit.corekit.fields.numbers reads a word into value subfields and a remainder. The layouts are concrete RadiotapField schemas, per the ruling on feat(link): decode radiotap's optional fields (#2576) #2657.
  • make(): it takes each bitmap as a mapping and range-checks every subfield with _make_uint. known takes a member or an int, and a remainder that sets a subfield's bit raises ProtocolError.

Every subfield mask is checked against Linux, Wireshark and radiotap.org. Recomposed, every bitmap is identical to main across #2576's vectors and the fuzz cases, and every record rebuilds exactly.

Closes #2647

@JarryShaw JarryShaw added this to the PyPCAPKit v1.6 milestone Nov 2, 2026
@JarryShaw JarryShaw added feat Pull requests that add a new capability (feat: subject prefix) review: pending No verdict for the current head - never reviewed, or the head moved since the last one labels Nov 2, 2026
@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: pending No verdict for the current head - never reviewed, or the head moved since the last one labels Nov 2, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Nov 2, 2026
@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Nov 2, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES at e212650b0, from a Sonnet cross-review. The code is sound: every mask and known bit matches Linux and radiotap.org, the crawlers regenerate byte-identically, 9372 bitmap round trips are exact, and all 13 mutants are caught. One change is required:

  • Rebase onto 342fe7ebe. It merges as text, but feat(link): decode radiotap TLV items a producer cut short (#2655) #2690's test_radiotap_short_tlv_2655_unit.py fails six U-SIG subtests on the merged tree. They expect common as an int, and test_make_refuses_a_malformed_cut now raises on the int common rather than on the record it means to test. Update those cases to the mapping form.

Optional: BitmapField given a missing subfield key raises a bare KeyError, which should be FieldValueError.

- Split the MCS flags, HE data1 and data2, HE-MU flags1 and flags2, and U-SIG
  common into their value subfields, each an int, and the rest of their bits.
- Keep the rest as a member of a known-bits registry, so undefined bits still
  round-trip: HEData1Known, HEData2Known, HEMUFlags1Known, HEMUFlags2Known and
  USIGCommonKnown, crawled from radiotap.org, named after Linux's macros.
- Add corekit's BitmapField, a word split from its least-significant bit in
  its byte order, and VALUES to the shared flag crawler for value rows.
- make() takes each bitmap as a mapping of range-checked subfields, its known
  bits a member or an int; new data models for each word.
- Tests: layouts against Linux, Wireshark and radiotap.org, both round trips,
  the crawlers and BitmapField; update the #2576 and #2655 expectations.

The link, const, vendor, dumpkit, corekit, foundation, project and root
protocols legs pass.
@JarryShaw
JarryShaw force-pushed the feat/2647-radiotap-mixed-bitmaps branch from e212650 to ddf28f9 Compare November 2, 2026 22:44
@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Nov 2, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at ddf28f9fb, rebased onto 342fe7ebe. I checked the delta myself.

The link, const and corekit legs pass. All 7677 differential records rebuild exactly against the new base, and captures are identical.

@JarryShaw

Copy link
Copy Markdown
Owner Author

can actually use auto() in the generated IntFlag values?

@JarryShaw

Copy link
Copy Markdown
Owner Author

Needs deciding: whether the generated known-bits registries can use auto(). They can only partly, because their bits are not a contiguous run from bit 0.

  • HEData1Known starts at bit 2, since bits 0–1 hold the format value subfield.
  • HEData2Known jumps from bit 7 to bit 14, past the value subfields in between.

IntFlag's auto() gives the next power of two after the previous member, so it lands on the wrong bit wherever a value subfield or reserved bit sits in between. It also types as Any, which reg/apptype already works around with a cast.

  1. Keep explicit 1 << n in every generated registry.
  2. Use auto() for contiguous runs, with an explicit value at the first member and after each gap.
  3. Use auto() throughout, which would put bits in the wrong positions.

Recommendation: 1. Each line then states its radiotap.org bit, so the file reviews against the spec line by line. A dropped crawler row fails loudly instead of shifting every later bit, and it matches the #2576 registries. The PR stays at GOOD TO GO with 1 unless you pick otherwise.

@JarryShaw JarryShaw added the needs: decision Waiting on the maintainer to decide — not blocked by other work label Nov 2, 2026
@JarryShaw JarryShaw moved this from In review to Needs decision in PyPCAPKit Nov 2, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

okay take 1

@JarryShaw

Copy link
Copy Markdown
Owner Author

The owner chose 1, paraphrased: the generated known-bits registries keep explicit 1 << n values, with no auto(). That is how this PR already does it, so nothing changes, and it stays GOOD TO GO. needs: decision comes off.

@JarryShaw JarryShaw removed the needs: decision Waiting on the maintainer to decide — not blocked by other work label Nov 2, 2026
@JarryShaw
JarryShaw merged commit 6253a87 into main Nov 2, 2026
59 checks passed
@github-project-automation github-project-automation Bot moved this from Needs decision to Done in PyPCAPKit Nov 2, 2026
@JarryShaw
JarryShaw deleted the feat/2647-radiotap-mixed-bitmaps branch November 2, 2026 23:10
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Nov 2, 2026
JarryShaw added a commit that referenced this pull request Nov 2, 2026
…s, the cut schema lists, the TSO checksum cut and short ZigBee keys into 1.6.0 (#2449)

- Breaking: MH (#2700) refuses a mobility option, or a sub-option, QoS
  attribute or CGA extension of one, whose fields do not take its length,
  where 1.5.x rebuilt another; QualityOfServiceOption gains a required
  tc_reserved. Prefix lengths are held to their field's width, the NAI and
  service identifier makers count octets, and a long-form DER CGA key
  parses. Folded into the MH/DSS and makers' range-check entries, with a
  QoS entry of its own; old and new values measured against v1.5.1.
- Fixed: ListField zero-fills a cut list of schema items, bounded by
  ZERO_PAD_BUDGET_RATIO with no free band, and a SACK past the data raises
  ProtocolError where it raised FieldValueError (#2701); a Decryption
  Secrets Block made from a short parsed ZigBee key is written as captured,
  and zigbee_key_held's schema holds the octets given (#2697).
- Folded into unreleased entries: radiotap's mixed bitmaps, their
  known-bits registries and BitmapField (#2696), into the Radiotap entry;
  the TSO and AH checksum cut (#2699), into the checksum and contextvars
  entries; the zero-filled SETTINGS and IGMPv3 records and the IGMPv3
  Additional Data rebuild (#2701), into the HTTP/2 SETTINGS and IGMP
  entries, dropping HTTPv2.make's unreleased frame_length.
- No entry for the docstring-and-test-only be83061 (#2695).
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Pull requests that add a new capability (feat: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

feat(link): split radiotap's mixed bitmaps into value subfields and known-bit flags

1 participant