Skip to content

Add NAT64 (RFC 6052) embedding strategy#112

Open
zanbaldwin wants to merge 1 commit into
6.xfrom
z/nat64-strategy
Open

Add NAT64 (RFC 6052) embedding strategy#112
zanbaldwin wants to merge 1 commit into
6.xfrom
z/nat64-strategy

Conversation

@zanbaldwin
Copy link
Copy Markdown
Member

NAT64 embedding strategy with named constructors for: well-known prefix, local-use prefix, and network-specific prefix.

NAT64 embedding strategy with named constructors for: well-known prefix, local-use prefix, and network-specific prefix.
@zanbaldwin zanbaldwin self-assigned this Jun 7, 2026
@zanbaldwin zanbaldwin added the feature New feature (minor version bump) label Jun 7, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 7, 2026

Greptile Summary

Adds a Nat64 embedding strategy implementing RFC 6052 § 2.2, covering all six permitted NAT64 prefix lengths (32, 40, 48, 56, 64, 96 bits). The class uses named constructors (wellKnown(), localUse(), networkSpecific()) instead of a public constructor, and correctly handles the reserved octet at bits 64–71 that interrupts the embedded IPv4 address for all prefix lengths other than /96.

  • src/Strategy/Nat64.php: new strategy class; extract() stitches IPv4 bytes from either side of the reserved octet, pack() inserts a zero reserved octet and pads the suffix to zero, isEmbedded() uses a pure prefix-membership check consistent with RFC 6146 § 3.5.
  • tests/Strategy/Nat64Test.php and tests/DataProvider/Strategy/Nat64.php: comprehensive test suite covering all six prefix lengths, the WKP, local-use, and network-specific named constructors, non-canonical (non-zero reserved octet / non-zero suffix) round-trip behaviour, and RFC 6052 § 2.4 Table 1 reference vectors.

Confidence Score: 5/5

This PR is safe to merge; the new strategy is self-contained and does not modify any existing code paths.

The reserved-octet stitching logic in extract() and pack() was traced manually against all six prefix lengths and matches the RFC 6052 § 2.2–2.3 specification exactly. The test suite includes the RFC 6052 § 2.4 Table 1 reference vectors, non-canonical round-trip cases, and invalid-input exception paths. No existing strategy or utility code was changed.

No files require special attention.

Important Files Changed

Filename Overview
src/Strategy/Nat64.php New strategy implementing RFC 6052 § 2.2; positional extraction/packing logic verified correct for all 6 prefix lengths including the reserved-octet stitching.
tests/DataProvider/Strategy/Nat64.php Test data includes RFC 6052 § 2.4 Table 1 reference vectors, non-canonical round-trip cases, invalid-length inputs, and non-matching prefix checks.
tests/Strategy/Nat64Test.php Comprehensive PHPUnit test class covering all three named constructors, exception paths, prefix-zeroing behaviour, and non-canonical round-trips.
docs/05-strategies.md Documentation updated with NAT64 section; per-prefix-length format tables and named-constructor descriptions are accurate.
CHANGELOG.md Changelog entry added for the NAT64 strategy with RFC references.

Reviews (1): Last reviewed commit: "feature(strategy): ✨ add NAT64 (RFC 6052..." | Re-trigger Greptile

@zanbaldwin
Copy link
Copy Markdown
Member Author

Is this what you had in mind, @Roman3349?

<?php

$prefix = IPv6::factory('2001:db8:122:300::');
$strategy = Nat64::networkSpecific($prefix, 56);

$ip = Multi::factory('2001:0db8:0122:03c0:0000:0221:0000:0000', $strategy);
$v4 = var_dump($ip->getDotAddress());
var_dump($v4); // string(10) "192.0.2.33"

I would really appreciate it if you could review this, if you have the time next week 🙂

@Roman3349
Copy link
Copy Markdown

@zanbaldwin Yes, that's fine. The only thing is that $cidr must always be 96 (128-32), so I would omit that argument from the Nat64::networkSpecific function.

@zanbaldwin
Copy link
Copy Markdown
Member Author

The RFC defines any of the following CIDRs as valid: 32, 40, 48, 56, 64, or 96. Depending on the CIDR provided, the IPv4 address is embedded at different positions. (See RFC 6052 § 2.4 Table 1 for examples).

@Roman3349 But yes, the convention for real-world deployments is to almost always use /96. I'll keep CIDR $length as an argument purely because that's what the RFC says.

I'm going to merge this soon (once I figure out the best order to merge the open PRs without causing conflicts). Let me know if you have any other suggestions for future pull requests 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature (minor version bump)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants