From 6ba34bb4421e4e18f990c154c79c7a36f847c2ea Mon Sep 17 00:00:00 2001 From: Damilola Bello Date: Sun, 29 Mar 2020 23:43:06 -0400 Subject: [PATCH] Convert IPv4 mapped IPv6 subnet masks to 4 bytes from 16 bytes (using the last 4 bytes). --- net/ip.go | 10 ++++++++++ net/ip_test.go | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/net/ip.go b/net/ip.go index 1ce30e8..76c0ecc 100644 --- a/net/ip.go +++ b/net/ip.go @@ -177,6 +177,7 @@ type Network struct { // NewNetwork returns Network built using given net.IPNet. func NewNetwork(ipNet net.IPNet) Network { + ipNet = getNetwork(ipNet) return Network{ IPNet: ipNet, Number: NewNetworkNumber(ipNet.IP), @@ -270,3 +271,12 @@ func NextIP(ip net.IP) net.IP { func PreviousIP(ip net.IP) net.IP { return NewNetworkNumber(ip).Previous().ToIP() } + +// getNetwork converts IPv4 mapped IPv6 subnet masks to 4 bytes. +// E.g. ::ffff:d1ad:35a7/128 get converted to 209.173.54.167/32. /128 becomes /32, /120 becomes /24 and so on. +func getNetwork(network net.IPNet) net.IPNet { + if network.IP.To4() != nil && len(network.Mask) == net.IPv6len { + network.Mask = network.Mask[12:16] + } + return network +} diff --git a/net/ip_test.go b/net/ip_test.go index 30e6407..d525be9 100644 --- a/net/ip_test.go +++ b/net/ip_test.go @@ -17,6 +17,7 @@ func TestNewNetworkNumber(t *testing.T) { {nil, nil, "nil input"}, {net.IP([]byte{1, 1, 1, 1, 1}), nil, "bad input"}, {net.ParseIP("128.0.0.0"), NetworkNumber([]uint32{2147483648}), "IPv4"}, + {net.ParseIP("::ffff:8000:0"), NetworkNumber([]uint32{2147483648}), "IPv4"}, { net.ParseIP("2001:0db8::ff00:0042:8329"), NetworkNumber([]uint32{536939960, 0, 65280, 4358953}), @@ -126,6 +127,7 @@ func TestNetworkNumberNext(t *testing.T) { {"0.0.0.0", "0.0.0.1", "IPv4 basic"}, {"0.0.0.255", "0.0.1.0", "IPv4 rollover"}, {"0.255.255.255", "1.0.0.0", "IPv4 consecutive rollover"}, + {"::ffff:ff:ffff", "1.0.0.0", "IPv4 consecutive rollover"}, {"8000::0", "8000::1", "IPv6 basic"}, {"0::ffff", "0::1:0", "IPv6 rollover"}, {"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "1::", "IPv6 consecutive rollover"}, @@ -149,6 +151,7 @@ func TestNeworkNumberPrevious(t *testing.T) { {"0.0.0.1", "0.0.0.0", "IPv4 basic"}, {"0.0.1.0", "0.0.0.255", "IPv4 rollover"}, {"1.0.0.0", "0.255.255.255", "IPv4 consecutive rollover"}, + {"1.0.0.0", "::ffff:ff:ffff", "IPv4 consecutive rollover"}, {"8000::1", "8000::0", "IPv6 basic"}, {"0::1:0", "0::ffff", "IPv6 rollover"}, {"1::0", "0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "IPv6 consecutive rollover"}, @@ -225,6 +228,15 @@ func TestNewNetwork(t *testing.T) { assert.Equal(t, NetworkNumberMask{math.MaxUint32 - uint32(math.MaxUint8)}, n.Mask) } +func TestNewNetwork2(t *testing.T) { + _, ipNet, _ := net.ParseCIDR("::ffff:c080:0/120") + n := NewNetwork(*ipNet) + + assert.Equal(t, *&ipNet.IP, n.IPNet.IP) + assert.Equal(t, NetworkNumber{3229614080}, n.Number) + assert.Equal(t, NetworkNumberMask{math.MaxUint32 - uint32(math.MaxUint8)}, n.Mask) +} + func TestNetworkMasked(t *testing.T) { cases := []struct { network string @@ -257,6 +269,7 @@ func TestNetworkEqual(t *testing.T) { name string }{ {"192.128.0.0/24", "192.128.0.0/24", true, "IPv4 equals"}, + {"192.128.0.0/24", "::ffff:c080:0/120", true, "IPv4 equals"}, {"192.128.0.0/24", "192.128.0.0/23", false, "IPv4 not equals"}, {"8000::/24", "8000::/24", true, "IPv6 equals"}, {"8000::/24", "8000::/23", false, "IPv6 not equals"},