Rename the constants to IP4arpa and IP6arpa (shorter and exported) and make IsReverse return the type of the reverse zone which could be handy for some callers. Also add tests for IsReverse()
81 lines
2 KiB
Go
81 lines
2 KiB
Go
package dnsutil
|
|
|
|
import (
|
|
"net"
|
|
"strings"
|
|
)
|
|
|
|
// 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:
|
|
return ""
|
|
}
|
|
|
|
// Reverse the segments and then combine them.
|
|
return f(strings.Split(search, "."))
|
|
}
|
|
|
|
// 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
|
|
}
|
|
return 0
|
|
}
|
|
|
|
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 {
|
|
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."
|
|
)
|