mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
common/helpers: rename PrefixTo16 to PrefixTo6
Move it to common/helpers/ipv6.go and use it where needed.
This commit is contained in:
@@ -13,9 +13,10 @@ var (
|
||||
z6noz = *(*uint64)(unsafe.Add(unsafe.Pointer(&someIPv6), 16))
|
||||
)
|
||||
|
||||
// AddrTo6 maps an IPv4 to an IPv4-mapped IPv6 and returns an IPv6 unmodified.
|
||||
// This is unsafe, but there is a test to ensure netip.Addr is like we expect.
|
||||
// Copying a unique.Handle bypass reference count, but z6noz is "static".
|
||||
// AddrTo6 maps an IPv4 address to an IPv4-mapped IPv6 address. It returns an
|
||||
// IPv6 address unmodified. This is unsafe, but there is a test to ensure
|
||||
// netip.Addr is like we expect. Copying a unique.Handle bypass reference count,
|
||||
// but z6noz is "static".
|
||||
//
|
||||
// This would be trivial to implement inside netip:
|
||||
//
|
||||
@@ -32,3 +33,22 @@ func AddrTo6(ip netip.Addr) netip.Addr {
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
// PrefixTo6 maps an IPv4 prefix to an IPv4-mapped IPv6 prefix. It returns an
|
||||
// IPv6 prefix unmodified.
|
||||
func PrefixTo6(prefix netip.Prefix) netip.Prefix {
|
||||
if prefix.Addr().Is4() {
|
||||
return netip.PrefixFrom(AddrTo6(prefix.Addr()), prefix.Bits()+96)
|
||||
}
|
||||
return prefix
|
||||
}
|
||||
|
||||
// UnmapPrefix unmaps a IPv4-mapped IPv6 prefix to IPv4 if it is one. Otherwise,
|
||||
// it returns the provided prefix unmodified.
|
||||
func UnmapPrefix(prefix netip.Prefix) netip.Prefix {
|
||||
if prefix.Addr().Is4In6() && prefix.Bits() >= 96 {
|
||||
ipv4Addr := prefix.Addr().Unmap()
|
||||
return netip.PrefixFrom(ipv4Addr, prefix.Bits()-96)
|
||||
}
|
||||
return prefix
|
||||
}
|
||||
|
||||
@@ -30,6 +30,44 @@ func TestAddrTo6(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrefixTo6(t *testing.T) {
|
||||
cases := []struct {
|
||||
input netip.Prefix
|
||||
output netip.Prefix
|
||||
}{
|
||||
{netip.Prefix{}, netip.Prefix{}},
|
||||
{netip.MustParsePrefix("192.168.1.0/24"), netip.MustParsePrefix("::ffff:192.168.1.0/120")},
|
||||
{netip.MustParsePrefix("2a01:db8::/64"), netip.MustParsePrefix("2a01:db8::/64")},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
got := helpers.PrefixTo6(tc.input)
|
||||
if diff := helpers.Diff(got, tc.output); diff != "" {
|
||||
t.Errorf("PrefixTo6(%s) (-got, +want):\n%s", tc.input, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmapPrefix(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{"0.0.0.0/0", "0.0.0.0/0"},
|
||||
{"::/0", "::/0"},
|
||||
{"192.168.12.0/24", "192.168.12.0/24"},
|
||||
{"2001:db8::/52", "2001:db8::/52"},
|
||||
{"::ffff:192.168.12.0/120", "192.168.12.0/24"},
|
||||
{"::ffff:0.0.0.0/0", "::ffff:0.0.0.0/0"},
|
||||
{"::ffff:0.0.0.0/96", "0.0.0.0/0"},
|
||||
} {
|
||||
prefix := netip.MustParsePrefix(tc.input)
|
||||
got := helpers.UnmapPrefix(prefix).String()
|
||||
if diff := helpers.Diff(got, tc.output); diff != "" {
|
||||
t.Errorf("UnmapPrefix(%q) (-got, +want):\n%s", tc.input, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetIPAddrStructure(t *testing.T) {
|
||||
var addr netip.Addr
|
||||
addrType := reflect.TypeOf(addr)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 Free Mobile
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
package helpers
|
||||
|
||||
import "net/netip"
|
||||
|
||||
// UnmapPrefix unmaps a IPv4-mapped IPv6 prefix to IPv4 if it is one. Otherwise,
|
||||
// it returns the provided prefix unmodified.
|
||||
func UnmapPrefix(prefix netip.Prefix) netip.Prefix {
|
||||
if prefix.Addr().Is4In6() && prefix.Bits() >= 96 {
|
||||
ipv4Addr := prefix.Addr().Unmap()
|
||||
return netip.PrefixFrom(ipv4Addr, prefix.Bits()-96)
|
||||
}
|
||||
return prefix
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 Free Mobile
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
package helpers_test
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"akvorado/common/helpers"
|
||||
)
|
||||
|
||||
func TestUnmapPrefix(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{"0.0.0.0/0", "0.0.0.0/0"},
|
||||
{"::/0", "::/0"},
|
||||
{"192.168.12.0/24", "192.168.12.0/24"},
|
||||
{"2001:db8::/52", "2001:db8::/52"},
|
||||
{"::ffff:192.168.12.0/120", "192.168.12.0/24"},
|
||||
{"::ffff:0.0.0.0/0", "::ffff:0.0.0.0/0"},
|
||||
{"::ffff:0.0.0.0/96", "0.0.0.0/0"},
|
||||
} {
|
||||
prefix := netip.MustParsePrefix(tc.input)
|
||||
got := helpers.UnmapPrefix(prefix).String()
|
||||
if diff := helpers.Diff(got, tc.output); diff != "" {
|
||||
t.Errorf("UnmapPrefix(%q) (-got, +want):\n%s", tc.input, diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,16 +221,6 @@ func SubnetMapUnmarshallerHook[V any]() mapstructure.DecodeHookFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// PrefixTo16 converts an IPv4 prefix to an IPv4-mapped IPv6 prefix.
|
||||
// IPv6 prefixes are returned as-is.
|
||||
func PrefixTo16(prefix netip.Prefix) netip.Prefix {
|
||||
if prefix.Addr().Is6() {
|
||||
return prefix
|
||||
}
|
||||
// Convert IPv4 to IPv4-mapped IPv6
|
||||
return netip.PrefixFrom(AddrTo6(prefix.Addr()), prefix.Bits()+96)
|
||||
}
|
||||
|
||||
// SubnetMapParseKey parses a prefix or an IP address into a netip.Prefix that
|
||||
// can be used in a map.
|
||||
func SubnetMapParseKey(k string) (netip.Prefix, error) {
|
||||
@@ -240,7 +230,7 @@ func SubnetMapParseKey(k string) (netip.Prefix, error) {
|
||||
if err != nil {
|
||||
return netip.Prefix{}, err
|
||||
}
|
||||
return PrefixTo16(key), nil
|
||||
return PrefixTo6(key), nil
|
||||
}
|
||||
// IP address
|
||||
key, err := netip.ParseAddr(k)
|
||||
@@ -248,7 +238,7 @@ func SubnetMapParseKey(k string) (netip.Prefix, error) {
|
||||
return netip.Prefix{}, err
|
||||
}
|
||||
if key.Is4() {
|
||||
return PrefixTo16(netip.PrefixFrom(key, 32)), nil
|
||||
return PrefixTo6(netip.PrefixFrom(key, 32)), nil
|
||||
}
|
||||
return netip.PrefixFrom(key, 128), nil
|
||||
}
|
||||
|
||||
@@ -549,50 +549,6 @@ func TestSubnetMapString(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPrefixTo16(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "IPv4 prefix",
|
||||
input: "192.0.2.0/24",
|
||||
expected: "::ffff:192.0.2.0/120",
|
||||
},
|
||||
{
|
||||
name: "IPv4 host",
|
||||
input: "192.0.2.1/32",
|
||||
expected: "::ffff:192.0.2.1/128",
|
||||
},
|
||||
{
|
||||
name: "IPv6 prefix unchanged",
|
||||
input: "2001:db8::/64",
|
||||
expected: "2001:db8::/64",
|
||||
},
|
||||
{
|
||||
name: "IPv6 host unchanged",
|
||||
input: "2001:db8::1/128",
|
||||
expected: "2001:db8::1/128",
|
||||
},
|
||||
{
|
||||
name: "IPv4-mapped IPv6 unchanged",
|
||||
input: "::ffff:192.0.2.0/120",
|
||||
expected: "::ffff:192.0.2.0/120",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
prefix := netip.MustParsePrefix(tc.input)
|
||||
result := helpers.PrefixTo16(prefix)
|
||||
if result.String() != tc.expected {
|
||||
t.Fatalf("PrefixTo16(%s) = %s, want %s", tc.input, result, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubnetMapSupernets(t *testing.T) {
|
||||
t.Run("nil", func(t *testing.T) {
|
||||
var sm *helpers.SubnetMap[string]
|
||||
|
||||
Reference in New Issue
Block a user