package utils import ( "net" "strings" "github.com/sirupsen/logrus" ) // Based on github.com/coredns/coredns/plugin/pkg/dnsutil/reverse.go // IsReverse returns 0 is name is not in a reverse zone. Anything > 0 indicates // name is in a reverse zone. The returned integer will be 1 for in-addr.arpa. (IPv4) // and 2 for ip6.arpa. (IPv6). func IsReverse(name string) int { if strings.HasSuffix(name, IP4arpa) { return 1 } if strings.HasSuffix(name, IP6arpa) { return 2 } logrus.Debug("REVERSE : Not Reverse") return 0 } // ExtractAddressFromReverse turns a standard PTR reverse record name // into an IP address. This works for ipv4 or ipv6. // // 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion // fails the empty string is returned. func ExtractAddressFromReverse(reverseName string) string { search := "" f := reverse switch { case strings.HasSuffix(reverseName, IP4arpa): search = strings.TrimSuffix(reverseName, IP4arpa) case strings.HasSuffix(reverseName, IP6arpa): search = strings.TrimSuffix(reverseName, IP6arpa) f = reverse6 default: logrus.Debug("REVERSE : ExtractAddressFromReverse : No result") return "" } // Reverse the segments and then combine them. return f(strings.Split(search, ".")) } func reverse(slice []string) string { for i := 0; i < len(slice)/2; i++ { j := len(slice) - i - 1 slice[i], slice[j] = slice[j], slice[i] } ip := net.ParseIP(strings.Join(slice, ".")).To4() if ip == nil { logrus.Debug("REVERSE : reverse : No result") logrus.Debug(ip) return "" } return ip.String() } // reverse6 reverse the segments and combine them according to RFC3596: // b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2 // is reversed to 2001:db8::567:89ab func reverse6(slice []string) string { for i := 0; i < len(slice)/2; i++ { j := len(slice) - i - 1 slice[i], slice[j] = slice[j], slice[i] } slice6 := []string{} for i := 0; i < len(slice)/4; i++ { slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], "")) } ip := net.ParseIP(strings.Join(slice6, ":")).To16() if ip == nil { return "" } return ip.String() } const ( // IP4arpa is the reverse tree suffix for v4 IP addresses. IP4arpa = ".in-addr.arpa." // IP6arpa is the reverse tree suffix for v6 IP addresses. IP6arpa = ".ip6.arpa." )