From cc413b214b19c85926ae4ddb3b88b85f76affe02 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Mon, 20 May 2019 23:29:07 +0700 Subject: net: add function to convert IPv6 into dot format This function only useful for expanding SPF macro "i" or when generating query for DNS PTR. --- lib/net/net.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/net/net_test.go | 19 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/lib/net/net.go b/lib/net/net.go index db926f4c..afbd7c19 100644 --- a/lib/net/net.go +++ b/lib/net/net.go @@ -7,6 +7,7 @@ package net import ( "errors" + "net" "strings" ) @@ -104,3 +105,54 @@ func IsTypeUDP(t Type) bool { func IsTypeTransport(t Type) bool { return IsTypeTCP(t) || IsTypeUDP(t) } + +// +// ToDotIPv6 convert the IPv6 address format from "::1" format into +// "0.0.0.0 ... 0.0.0.1". +// +// This function only useful for expanding SPF macro "i" or when generating +// query for DNS PTR. +// +func ToDotIPv6(ip net.IP) (out []byte) { + addrs := strings.Split(ip.String(), ":") + + var notempty int + for x := 0; x < len(addrs); x++ { + if len(addrs[x]) != 0 { + notempty++ + } + } + gap := 8 - notempty + + for x := 0; x < len(addrs); x++ { + addr := addrs[x] + + // Fill the gap "::" with one or more "0.0.0.0". + if len(addr) == 0 { + for ; gap > 0; gap-- { + if len(out) > 0 { + out = append(out, '.') + } + out = append(out, []byte("0.0.0.0")...) + } + continue + } + + // Fill the sub address with zero. + for y := len(addr); y < 4; y++ { + if len(out) > 0 { + out = append(out, '.') + } + out = append(out, '0') + } + + for y := 0; y < len(addr); y++ { + if len(out) > 0 { + out = append(out, '.') + } + out = append(out, addr[y]) + } + } + + return +} diff --git a/lib/net/net_test.go b/lib/net/net_test.go index 66dc2233..4fe506a2 100644 --- a/lib/net/net_test.go +++ b/lib/net/net_test.go @@ -5,6 +5,7 @@ package net import ( + "net" "testing" "github.com/shuLhan/share/lib/test" @@ -189,3 +190,21 @@ func TestIsTypeTransport(t *testing.T) { test.Assert(t, "IsTypeTransport", c.exp, got, true) } } + +func TestToDotIPv6(t *testing.T) { + cases := []struct { + ip net.IP + exp []byte + }{{ + ip: net.ParseIP("2001:db8::68"), + exp: []byte("2.0.0.1.0.d.b.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.6.8"), + }, { + ip: net.ParseIP("::1"), + exp: []byte("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1"), + }} + + for _, c := range cases { + got := ToDotIPv6(c.ip) + test.Assert(t, "ToDotIPv6", c.exp, got, true) + } +} -- cgit v1.3