From 940fb7ac4d24597a841756487edce200209c7e2e Mon Sep 17 00:00:00 2001
From: Daniel Czerwonk <daniel@dan-nrw.de>
Date: Sun, 1 Jul 2018 19:48:56 +0200
Subject: [PATCH] contains IPv6 implementation

---
 net/prefix.go      | 16 +++++++++++++++-
 net/prefix_test.go | 24 ++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/net/prefix.go b/net/prefix.go
index f75c2004..5abd32f1 100644
--- a/net/prefix.go
+++ b/net/prefix.go
@@ -70,7 +70,7 @@ func (pfx Prefix) Contains(x Prefix) bool {
 		return pfx.containsIPv4(x)
 	}
 
-	panic("No IPv6 support yet!")
+	return pfx.containsIPv6(x)
 }
 
 func (pfx Prefix) containsIPv4(x Prefix) bool {
@@ -78,6 +78,20 @@ func (pfx Prefix) containsIPv4(x Prefix) bool {
 	return (pfx.addr.ToUint32() & mask) == (x.addr.ToUint32() & mask)
 }
 
+func (pfx Prefix) containsIPv6(x Prefix) bool {
+	var maskHigh, maskLow uint64
+	if pfx.pfxlen <= 64 {
+		maskHigh = math.MaxUint32 << (64 - pfx.pfxlen)
+		maskLow = uint64(0)
+	} else {
+		maskHigh = math.MaxUint32
+		maskLow = math.MaxUint32 << (128 - pfx.pfxlen)
+	}
+
+	return pfx.addr.higher&maskHigh&maskHigh == x.addr.higher&maskHigh&maskHigh &&
+		pfx.addr.lower&maskHigh&maskLow == x.addr.lower&maskHigh&maskLow
+}
+
 // Equal checks if pfx and x are equal
 func (pfx Prefix) Equal(x Prefix) bool {
 	return pfx == x
diff --git a/net/prefix_test.go b/net/prefix_test.go
index 4428a4e8..ccb05a7d 100644
--- a/net/prefix_test.go
+++ b/net/prefix_test.go
@@ -240,6 +240,30 @@ func TestContains(t *testing.T) {
 			},
 			expected: false,
 		},
+		{
+			name: "IPv6: 2001:678:1e0:100::/56 is subnet of 2001:678:1e0::/48",
+			a: Prefix{
+				addr:   IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0, 0, 0, 0, 0),
+				pfxlen: 48,
+			},
+			expected: true,
+			b: Prefix{
+				addr:   IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0x100, 0, 0, 0, 0),
+				pfxlen: 56,
+			},
+		},
+		{
+			name: "IPv6: 2001:678:1e0:100::/56 is subnet of 2001:678:1e0::/48",
+			a: Prefix{
+				addr:   IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0x200, 0, 0, 0, 0),
+				pfxlen: 56,
+			},
+			b: Prefix{
+				addr:   IPv6FromBlocks(0x2001, 0x678, 0x1e0, 0x100, 0, 0, 0, 0),
+				pfxlen: 64,
+			},
+			expected: false,
+		},
 	}
 
 	for _, test := range tests {
-- 
GitLab