diff --git a/client/client.go b/client/client.go index 22c663d6..3172a8d1 100644 --- a/client/client.go +++ b/client/client.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "encoding/hex" "errors" "fmt" "io" @@ -410,6 +411,17 @@ func QueryDNS(queryType, queryName, url string) (connected bool, dnsRcode string url = fmt.Sprintf("%s:%d", url, dnsPort) } queryTypeAsUint16 := dns.StringToType[queryType] + // Special handling: if this is a PTR query and queryName looks like a plain IP, + // convert it to the proper reverse lookup domain automatically. + if queryTypeAsUint16 == dns.TypePTR && + !strings.HasSuffix(queryName, ".in-addr.arpa.") && + !strings.HasSuffix(queryName, ".ip6.arpa.") { + if rev, convErr := reverseNameForIP(queryName); convErr == nil { + queryName = rev + } else { + return false, "", nil, convErr + } + } c := new(dns.Client) m := new(dns.Msg) m.SetQuestion(queryName, queryTypeAsUint16) @@ -481,3 +493,27 @@ func rdapQuery(hostname string) (*whois.Response, error) { } return &response, nil } + +// helper to reverse IP and add in-addr.arpa. IPv4 and IPv6 +func reverseNameForIP(ipStr string) (string, error) { + ip := net.ParseIP(ipStr) + if ip == nil { + return "", fmt.Errorf("invalid IP: %s", ipStr) + } + + if ipv4 := ip.To4(); ipv4 != nil { + parts := strings.Split(ipv4.String(), ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + return strings.Join(parts, ".") + ".in-addr.arpa.", nil + } + + ip = ip.To16() + hexStr := hex.EncodeToString(ip) + nibbles := strings.Split(hexStr, "") + for i, j := 0, len(nibbles)-1; i < j; i, j = i+1, j-1 { + nibbles[i], nibbles[j] = nibbles[j], nibbles[i] + } + return strings.Join(nibbles, ".") + ".ip6.arpa.", nil +} \ No newline at end of file diff --git a/client/client_test.go b/client/client_test.go index 92513148..10bfec16 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -451,6 +451,16 @@ func TestQueryDNS(t *testing.T) { expectedDNSCode: "NOERROR", expectedBody: "dns.google.", }, + { + name: "test Config with type PTR and forward IP / no in-addr", + inputDNS: dns.Config{ + QueryType: "PTR", + QueryName: "1.0.0.1", + }, + inputURL: "1.1.1.1", + expectedDNSCode: "NOERROR", + expectedBody: "one.one.one.one.", + }, { name: "test Config with fake type and retrieve error", inputDNS: dns.Config{