From e6d9f1a0ab4e440a41fe5bad3741ac1ad6c2620f Mon Sep 17 00:00:00 2001 From: sukun Date: Fri, 30 Jun 2023 00:47:47 +0530 Subject: [PATCH] manet: add function to test if address is NAT64 IPv4 converted IPv6 address --- net/ip.go | 11 +++++++++++ net/ip_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 net/ip_test.go diff --git a/net/ip.go b/net/ip.go index 1cf9a77..4e97f4b 100644 --- a/net/ip.go +++ b/net/ip.go @@ -1,6 +1,7 @@ package manet import ( + "bytes" "net" ma "github.com/multiformats/go-multiaddr" @@ -116,3 +117,13 @@ func zoneless(m ma.Multiaddr) ma.Multiaddr { return m } } + +var NAT64WellKnownPrefix = [4]byte{0x0, 0x64, 0xff, 0x9b} + +// IsNAT64IPv4ConvertedIPv6Addr returns whether addr is an IPv6 address that begins with +// the well known prefix "64:ff9b" used for NAT64 Translation +// see RFC 6052 +func IsNAT64IPv4ConvertedIPv6Addr(addr ma.Multiaddr) bool { + c, _ := ma.SplitFirst(addr) + return c.Protocol().Code == ma.P_IP6 && bytes.HasPrefix(c.RawValue(), NAT64WellKnownPrefix[:]) +} diff --git a/net/ip_test.go b/net/ip_test.go new file mode 100644 index 0000000..351337d --- /dev/null +++ b/net/ip_test.go @@ -0,0 +1,44 @@ +package manet + +import ( + "fmt" + "testing" + + ma "github.com/multiformats/go-multiaddr" +) + +func TestIsWellKnownPrefixIPv4ConvertedIPv6Address(t *testing.T) { + cases := []struct { + addr ma.Multiaddr + want bool + failureReason string + }{ + { + addr: ma.StringCast("/ip4/1.2.3.4/tcp/1234"), + want: false, + failureReason: "ip4 addresses should return false", + }, + { + addr: ma.StringCast("/ip6/1::4/tcp/1234"), + want: false, + failureReason: "ip6 addresses doesn't have wellknown prefix", + }, + { + addr: ma.StringCast("/ip6/::1/tcp/1234"), + want: false, + failureReason: "localhost addresses should return false", + }, + { + addr: ma.StringCast("/ip6/64:ff9b::192.0.1.2/tcp/1234"), + want: true, + failureReason: "ip6 address begins with well-known prefix", + }, + } + for i, tc := range cases { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + if IsNAT64IPv4ConvertedIPv6Addr(tc.addr) != tc.want { + t.Fatalf("%s %s", tc.addr, tc.failureReason) + } + }) + } +}