1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
package zone
import (
"net"
)
// Zone suffixes.
var (
ip4Arpa = ".in-addr.arpa"
ip6Arpa = ".ip6.arpa"
)
// reverse takes an IPv4 or IPv6 address and returns the matching ARPA record.
func reverse(ip net.IP) (arpa string) {
if ip == nil {
return ""
}
// Deal with IPv4.
if ip.To4() != nil {
return uitoa(uint(ip[15])) + "." + uitoa(uint(ip[14])) + "." + uitoa(uint(ip[13])) + "." + uitoa(uint(ip[12])) + ip4Arpa + "."
}
// Deal with IPv6.
buf := make([]byte, 0, len(ip)*4+len(ip6Arpa))
// Add it, in reverse, to the buffer.
for i := len(ip) - 1; i >= 0; i-- {
v := ip[i]
buf = append(buf, hexDigit[v&0xF],
'.',
hexDigit[v>>4],
'.')
}
// Add the suffix.
buf = append(buf, ip6Arpa[1:]+"."...)
return string(buf)
}
// Convert unsigned integer to decimal string.
func uitoa(val uint) string {
// Avoid string allocation.
if val == 0 {
return "0"
}
// Big enough for 64bit value base 10.
var buf [20]byte
i := len(buf) - 1
for val >= 10 {
q := val / 10
buf[i] = byte('0' + val - q*10)
i--
val = q
}
// val < 10
buf[i] = byte('0' + val)
return string(buf[i:])
}
const hexDigit = "0123456789abcdef"
|