1package dnsutil 2 3import ( 4 "net" 5 "strings" 6) 7 8// ExtractAddressFromReverse turns a standard PTR reverse record name 9// into an IP address. This works for ipv4 or ipv6. 10// 11// 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion 12// fails the empty string is returned. 13func ExtractAddressFromReverse(reverseName string) string { 14 search := "" 15 16 f := reverse 17 18 switch { 19 case strings.HasSuffix(reverseName, IP4arpa): 20 search = strings.TrimSuffix(reverseName, IP4arpa) 21 case strings.HasSuffix(reverseName, IP6arpa): 22 search = strings.TrimSuffix(reverseName, IP6arpa) 23 f = reverse6 24 default: 25 return "" 26 } 27 28 // Reverse the segments and then combine them. 29 return f(strings.Split(search, ".")) 30} 31 32// IsReverse returns 0 is name is not in a reverse zone. Anything > 0 indicates 33// name is in a reverse zone. The returned integer will be 1 for in-addr.arpa. (IPv4) 34// and 2 for ip6.arpa. (IPv6). 35func IsReverse(name string) int { 36 if strings.HasSuffix(name, IP4arpa) { 37 return 1 38 } 39 if strings.HasSuffix(name, IP6arpa) { 40 return 2 41 } 42 return 0 43} 44 45func reverse(slice []string) string { 46 for i := 0; i < len(slice)/2; i++ { 47 j := len(slice) - i - 1 48 slice[i], slice[j] = slice[j], slice[i] 49 } 50 ip := net.ParseIP(strings.Join(slice, ".")).To4() 51 if ip == nil { 52 return "" 53 } 54 return ip.String() 55} 56 57// reverse6 reverse the segments and combine them according to RFC3596: 58// 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 59// is reversed to 2001:db8::567:89ab 60func reverse6(slice []string) string { 61 for i := 0; i < len(slice)/2; i++ { 62 j := len(slice) - i - 1 63 slice[i], slice[j] = slice[j], slice[i] 64 } 65 slice6 := []string{} 66 for i := 0; i < len(slice)/4; i++ { 67 slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], "")) 68 } 69 ip := net.ParseIP(strings.Join(slice6, ":")).To16() 70 if ip == nil { 71 return "" 72 } 73 return ip.String() 74} 75 76const ( 77 // IP4arpa is the reverse tree suffix for v4 IP addresses. 78 IP4arpa = ".in-addr.arpa." 79 // IP6arpa is the reverse tree suffix for v6 IP addresses. 80 IP6arpa = ".ip6.arpa." 81) 82