From b1ece11cb631aee120b0bffa2728315f4a026dda Mon Sep 17 00:00:00 2001 From: Yangyu Chen Date: Sun, 29 Dec 2024 19:25:17 +0800 Subject: [PATCH] feat: Handle NAT64 address query We can query the NAT64 address by the IPv4 address part of the NAT64 address. This is useful when we want to know the NAT64 address of a specific IPv4 address. We also add a new regex pattern to match the NAT64 address like 64:ff9b::1.1.1.1 . Signed-off-by: Yangyu Chen --- internal/db/db.go | 20 ++++++++++++++++++++ pkg/re/re.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/db/db.go b/internal/db/db.go index cf0bd100..93be3536 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -2,6 +2,8 @@ package db import ( "log" + "net" + "encoding/binary" "github.com/spf13/viper" @@ -72,6 +74,24 @@ func Find(typ dbif.QueryType, query string) *Result { if result, found := queryCache.Load(query); found { return result.(*Result) } + // Convert NAT64 64:ff9b::/96 to IPv4 + if typ == dbif.TypeIPv6 { + // Parse IPv6 address + ip := net.ParseIP(query) + if ip != nil { + ip6 := ip.To16() + ipu64 := binary.BigEndian.Uint64(ip6[:8]) + ipu64_2 := binary.BigEndian.Uint32(ip6[8:12]) + if ipu64 == 0x64ff9b00000000 && ipu64_2 == 0 { + // Convert to IPv4 + ipu32 := binary.BigEndian.Uint32(ip6[12:16]) + ip4 := make(net.IP, 4) + binary.BigEndian.PutUint32(ip4, ipu32) + query = ip4.String() + typ = dbif.TypeIPv4 + } + } + } db := GetDB(typ) result, err := db.Find(query) if err != nil { diff --git a/pkg/re/re.go b/pkg/re/re.go index 780b159b..53b0d7f8 100644 --- a/pkg/re/re.go +++ b/pkg/re/re.go @@ -9,7 +9,7 @@ var ( DomainRe = regexp.MustCompile(`([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z][-a-zA-Z]{0,62})`) IPv4Re = regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`) - IPv6Re = regexp.MustCompile(`fe80:(:[0-9a-fA-F]{1,4}){0,4}(%\w+)?|([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::[fF]{4}:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?::(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?`) + IPv6Re = regexp.MustCompile(`fe80:(:[0-9a-fA-F]{1,4}){0,4}(%\w+)?|([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|64:ff9b::(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|::[fF]{4}:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}|(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?::(([0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4})?`) ) func MaybeRegexp(s string) bool {