Skip to content

Implement the MH FMIPv6 fast-handover messages and options - #383

Merged
JarryShaw merged 1 commit into
mainfrom
feat/mh-fmipv6
Sep 15, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
feat/mh-fmipv6

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

First tranche of the MH work the Help Wanted page asks for. Takes message dispatch from 8/24 to 14/24 and mobility options from 17/71 to 20/71.

What is implemented

Messages, per :rfc:5568 unless noted:

# Message RFC
8 Fast Binding Update 5568 §6.2.2
9 Fast Binding Acknowledgment 5568 §6.2.3
10 Fast Neighbor Advertisement 4068 §6.3.3 (deprecated by 5568 §8)
11 Experimental Mobility Header 5096 §3
14 Handover Initiate 5568 §6.2.1.1 + 5949 §6.1.1
15 Handover Acknowledge 5568 §6.2.1.2 + 5949 §6.1.2

Options: 18 Experimental (RFC 5096 §4), 21 Binding Authorization Data for FMIPv6 (§6.4.5), 34 Mobility Header IPv6 Address/Prefix (§6.4.2 + erratum 1816).

Types 14 and 15 were added beyond the obvious 8–11 because they are the other half of RFC 5568's message set, and they are what the four already-generated handover_* / handoff_type const enums exist for — those were imported but never consumed until now.

Each type gets a read handler and a make counterpart, a schema, a data model, dispatch registration and docs, keeping the codebase's read/make invariant intact (verified programmatically: zero orphans on either side).

The two local enums, and why they are local

The project's rule is that registry-derived enums live in pcapkit/const/<proto>/ with a pcapkit/vendor/ crawler, and value sets with no registry stay in the protocol module. pcapkit/const/mh/ already holds 43 crawler-generated enums, so this tranche adds none there. But two value sets RFC 5568 defines inline have no IANA registry, and "no registry" means keep the enum in the module, not use a bare int:

  • FastBindingAcknowledgmentStatus (§6.2.3). It deliberately does not reuse pcapkit.const.mh.status_code.StatusCode: value 1 means "NCoA invalid" here but "prefix discovery necessary" there, and 131 means "incorrect interface identifier length" here but "home registration not supported" there. Typing the field as StatusCode would mislabel real packets.
  • IPv6AddressPrefixCode (§6.4.2), codes 1–4.

Both carry the const modules' _missing_ handling, so an unassigned value in a wild capture parses to Unassigned_N instead of raising. Placement follows pcapkit/protocols/misc/pcapng.py, which already defines PacketDirection/PacketReception locally — though that precedent uses bare enum.IntEnum with no unassigned handling, so this combines pcapng's placement with the const modules' robustness.

One deviation worth a reviewer's eye: the schema fields stay UInt8Field rather than EnumField. EnumField needs its namespace class at class-body time, and the schema module cannot import the protocol module — the protocol module imports the schema module, so it is a hard cycle. The enum is applied when the data model is built, which is exactly the split pcapng uses, and both class docstrings record why.

Deliberately not implemented

  • The three remaining CGA extensions are Exp_FFFD/FFFE/FFFF, RFC 4581 experimental code points with no defined layout. The existing opaque handler already is the faithful reading; implementing them would mean inventing a wire format.
  • BADF option length follows RFC 5568 §6.4.5's literal wording, which counts only the authenticator and excludes the 4-byte SPI — contradicting RFC 6275 §6.2.1's generic rule. Safe because RFC 5568 requires BADF be the last option and OptionField advances by bytes actually consumed; the total is reported as length + 6.
  • FBack status and the option-34 code are typed as the new local enums rather than shared registries, per above.

Tests

5 tests / 21 subtests added, in three layers:

  • RFC conformance — 7 hand-written byte strings laid out from the RFC figures, parsed and asserted field by field (e.g. FBU 1105 08 00 1234 | 1234 d000 000a | 0310 <addr> | 150c deadbeef → seq=0x1234, ack/home/key_mngt set, lla_compat clear, lifetime 40 s, BADF spi 0xdeadbeef). Each asserted 8-octet aligned.
  • Round trip — built with make, parsed with read, rebuilt from the parsed data model and asserted byte-identical to the original.
  • Enum coverage — every member parses, unassigned values do not raise, make accepts member / bare int / member-name.

Plus a regression test for bit-independent flag packing.

Full suite: 508 passed, 4 skipped, 315 subtests passed — exactly main plus this tranche, nothing else moved.

Remaining MH gap, for whoever takes the next tranche

10 message types (12 Home Agent Switch, 13 Heartbeat, 16 Binding Revocation, 17/18 Localized Routing, 19/20 Update Notification, 21 Flow Binding, 22/23 Subscription) and 51 options (17, 19, 20, 22–33, 35–70). The PMIPv6 cluster (RFC 5213, options 22–27) is the natural next one — self-contained, and handoff_type/access_type are already generated for it.

Two MH defects found while working here are filed separately and not fixed in this PR: #354 (_make_opt_pad grows a PadN by two octets per round trip) and #355 (a Pad1 option crashes parsing with struct.error). The round-trip tests here are padding-free by construction because of them, noted in a comment.

First tranche of the MH work the Help Wanted page asks for, taking message
dispatch from 8/24 to 14/24 and options from 17/71 to 20/71.

Messages, per RFC 5568 unless noted: 8 Fast Binding Update, 9 Fast Binding
Acknowledgment, 10 Fast Neighbor Advertisement (RFC 4068, deprecated by 5568),
11 Experimental (RFC 5096), 14 Handover Initiate and 15 Handover Acknowledge.
Options: 18 Experimental, 21 Binding Authorization Data for FMIPv6, 34 Mobility
Header IPv6 Address/Prefix. Each has a read handler, a make counterpart, a
schema, a data model, dispatch registration and docs, and each is covered by a
byte-level RFC conformance case and a byte-identical round trip.

Four handover_* and handoff_* const enums that were generated but never
imported are now consumed.

Two value sets get enums local to this module rather than const plus a vendor
crawler, because RFC 5568 defines them inline and IANA registers neither:
FastBindingAcknowledgmentStatus (6.2.3) and IPv6AddressPrefixCode (6.4.2). The
first cannot reuse pcapkit.const.mh.status_code.StatusCode - 1 and 131 mean
different things in the two lists, so that would mislabel real packets. Both
carry the const modules' _missing_ handling so an unassigned value parses
instead of raising. Placement follows pcapkit/protocols/misc/pcapng.py, which
already defines two enums locally.

The schema fields stay UInt8Field: EnumField needs its namespace at class-body
time and the schema module cannot import the protocol module, which imports it,
so the enum is applied when the data model is built, as pcapng does.

Not implemented, deliberately: the three remaining CGA extensions are RFC 4581
experimental code points with no defined layout, so the existing opaque handler
is already the faithful reading. BADF's length field follows RFC 5568's literal
wording, which excludes the SPI and contradicts RFC 6275's generic rule.

Also fixes two typos in the class docstring ("og", "resgitered").

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation is consistent with existing MH patterns and is backed by detailed RFC-based and round-trip tests, with only minor documentation wording to consider.

Pull request overview

This PR extends PyPCAPKit’s Mobility Header (MH) support by implementing additional FMIPv6 (and related experimental) MH message types and mobility options, including full read/make symmetry plus documentation and unit tests.

Changes:

  • Added MH dispatch + schema + data-model + constructor support for FMIPv6 messages (FBU/FBack/FNA/HI/HAck) and Experimental Mobility Header (EMH).
  • Added MH mobility option support for Experimental Mobility Option, BADF, and Mobility Header IPv6 Address/Prefix.
  • Added comprehensive unit tests (wire-format conformance + round-trip byte identity + local-enum coverage) and updated Sphinx docs to include the new APIs.
File summaries
File Description
tests/protocols/internet/test_mh_unit.py Adds FMIPv6/EMH message+option unit tests, including RFC wire-format and round-trip coverage.
pcapkit/protocols/schema/internet/mh.py Introduces new MH message/option schemas and related flag TypedDicts.
pcapkit/protocols/internet/mh.py Implements new MH message/option readers & makers, registers dispatch, and adds two module-local enums.
pcapkit/protocols/data/internet/mh.py Adds corresponding data models and type annotations for the new messages/options.
docs/source/pcapkit/protocols/internet/mh.rst Documents the new message/option handlers, schemas, data models, and local enums.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pcapkit/protocols/internet/mh.py
@JarryShaw
JarryShaw merged commit 5ba6ff0 into main Sep 15, 2026
50 checks passed
@JarryShaw
JarryShaw deleted the feat/mh-fmipv6 branch September 17, 2026 01:08
@JarryShaw JarryShaw added the feat Pull requests that add a new capability (feat: subject prefix) label Sep 22, 2026
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

None yet

Development

Successfully merging this pull request may close these issues.

2 participants