fix(orig_dest): pf_state_xport union fixes macOS DIOCNATLOOK struct size (rebased #2)#45
Merged
Merged
Conversation
…uct size `struct pfioc_natlook` uses `union pf_state_xport` for its four port fields, not bare `u16`. The union carries a `u32 spi` member, so it is 4 bytes (not 2), making the struct 84 bytes instead of 76. Because the DIOCNATLOOK ioctl number is computed at compile time from `size_of::<PfiocNatlook>()`, the wrong size yielded ioctl 0xC04C4417 instead of 0xC0544417. The kernel rejected the unrecognized number with ENOTTY, so every NAT lookup silently fell back to the getsockname heuristic. The old tail field order (`direction, log`) was also wrong; the kernel struct is `proto_variant, direction`. Adds size_of, offset_of, ioctl-number, and round-trip unit tests so the layout can't silently regress again. Co-authored-by: Nicholas Wright <Abica> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
madeye
force-pushed
the
fix/macos-pfioc-natlook-struct-layout
branch
from
June 30, 2026 06:41
818025d to
94aaaa2
Compare
|
Glad it was useful! Thanks for carrying it across the line and keeping the test suite intact. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rebase of #2 onto current
main(which has since gained IPv6 support), resolving the conflict and keeping @Abica's original analysis and tests. Credit to @Abica for the root-cause investigation.The bug
struct pfioc_natlookusesunion pf_state_xportfor its four port fields, not bareu16. That union includes au32 spimember, so it is 4 bytes, making the struct 84 bytes — not the 76 the old layout produced.Because the
DIOCNATLOOKioctl number is computed at compile time fromsize_of::<PfiocNatlook>(), the wrong size produced ioctl0xC04C4417instead of0xC0544417. The kernel rejects the unrecognized number withENOTTY, so every NAT lookup silently fell through to thegetsocknamefallback heuristic.This was masked in e2e tests because DIOCNATLOOK failure was logged only at
debugand the loopbackgetsocknamefallback happened to work. The old tail field order (direction, log) was also wrong — the kernel struct isproto_variant, direction.Changes vs. #2
Same struct/union fix and the same compile-time + unit-test coverage (
size_of,offset_of!, ioctl-number, round-trip, zero-init), re-applied on top of the IPv6-awareget_original_dest_pf. The DIOCNATLOOK failure log is also bumpeddebug→warnso future regressions are visible.Verification
cargo fmt --check,cargo clippy --all-targets -- -D warnings, andcargo testall pass on macOS — the 7 new pf-layout tests included (160 passed, 0 failed).Closes #2.
🤖 Generated with Claude Code