File: reverse.go

package info (click to toggle)
incus 6.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 26,092 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (63 lines) | stat: -rw-r--r-- 1,156 bytes parent folder | download | duplicates (6)
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"