AdGuardHome/util/dns.go
Simon Zolin 49a92605b8 + dns: respond to PTR requests for internal IP addresses from DHCP
Close #1682

Squashed commit of the following:

commit 2fad3544bf8853b1f8f19ad8b7bc8a490c96e533
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 17:32:45 2020 +0300

    minor

commit 7c17992424702d95e6de91f30e8ae2dfcd8de257
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:09:34 2020 +0300

    build

commit 16a52e11a015a97d3cbf30362482a4abd052192b
Merge: 7b6a73c8 2c47053c
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:08:32 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1682-dhcp-resolve

commit 7b6a73c84b5cb9a073a9dfb7d7bdecd22e1e1318
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:01:34 2020 +0300

    tests

commit c2654abb2e5e7b7e3a04e4ddb8e1064b37613929
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 1 15:15:13 2020 +0300

    + dnsforward: respond to PTR requests for internal IP addresses

    {[IP] => "host"} <- DNSforward <-(leases)-- DHCP
2020-06-23 12:13:13 +03:00

70 lines
1.3 KiB
Go

package util
import (
"net"
"strings"
)
// convert character to hex number
func charToHex(n byte) int8 {
if n >= '0' && n <= '9' {
return int8(n) - '0'
} else if (n|0x20) >= 'a' && (n|0x20) <= 'f' {
return (int8(n) | 0x20) - 'a' + 10
}
return -1
}
// parse IPv6 reverse address
func ipParseArpa6(s string) net.IP {
if len(s) != 63 {
return nil
}
ip6 := make(net.IP, 16)
for i := 0; i != 64; i += 4 {
// parse "0.1."
n := charToHex(s[i])
n2 := charToHex(s[i+2])
if s[i+1] != '.' || (i != 60 && s[i+3] != '.') ||
n < 0 || n2 < 0 {
return nil
}
ip6[16-i/4-1] = byte(n2<<4) | byte(n&0x0f)
}
return ip6
}
// ipReverse - reverse IP address: 1.0.0.127 -> 127.0.0.1
func ipReverse(ip net.IP) net.IP {
n := len(ip)
r := make(net.IP, n)
for i := 0; i != n; i++ {
r[i] = ip[n-i-1]
}
return r
}
// DNSUnreverseAddr - convert reversed ARPA address to a normal IP address
func DNSUnreverseAddr(s string) net.IP {
const arpaV4 = ".in-addr.arpa"
const arpaV6 = ".ip6.arpa"
if strings.HasSuffix(s, arpaV4) {
ip := strings.TrimSuffix(s, arpaV4)
ip4 := net.ParseIP(ip).To4()
if ip4 == nil {
return nil
}
return ipReverse(ip4)
} else if strings.HasSuffix(s, arpaV6) {
ip := strings.TrimSuffix(s, arpaV6)
return ipParseArpa6(ip)
}
return nil // unknown suffix
}