/
resolve_config_parser.go
68 lines (60 loc) · 1.88 KB
/
resolve_config_parser.go
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
64
65
66
67
68
package config
import (
"bytes"
"io/ioutil"
"net"
"regexp"
)
var (
defaultResolvConf = "/etc/resolv.conf"
nameServerRegex = regexp.MustCompile(`^\s*nameserver\s*(.+?)\s*$`)
)
// GetNameServersFromResolveConfig parses a file in the format of /etc/resolv.conf
// The resolve.conf format is described in resolv.conf(5):
//
// https://man7.org/linux/man-pages/man5/resolv.conf.5.html
//
// This function looks up at the lines starting with `nameserver`.
// There can be a single nameserver each line and maximum 3 (defined
// my MAXNS in resolv.h) in the file.
func GetNameServersFromResolveConfig(filePath string) ([]string, error) {
content, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
nameservers := ParseNameServers(content)
return nameservers, nil
}
// ParseNameServers parses an array of bytes and returns the nameservers
// The content should be of format of /etc/resolv.conf i.e.
// nameserver 12.0.0.3
func ParseNameServers(fileContent []byte) []string {
fileLines := bytes.Split(fileContent, []byte("\n"))
var nameservers []string
for _, currentLine := range fileLines {
var contentToParse = currentLine
var commentIndicatorIndex = bytes.Index(currentLine, []byte("#"))
if commentIndicatorIndex != -1 {
// Only check the content before the comment section
contentToParse = currentLine[:commentIndicatorIndex]
}
server := nameServerRegex.FindSubmatch(contentToParse)
if len(server) == 2 {
address := string(server[1])
if net.ParseIP(address) != nil {
nameservers = append(nameservers, address)
}
}
}
return nameservers
}
// GetSystemResolvers returns resolvers discovered via
// /etc/resolv.conf. If not valid resolvers are found, an empty array
// is returned.
func GetSystemResolvers() []string {
resolvers, err := GetNameServersFromResolveConfig(defaultResolvConf)
if err != nil {
return []string{}
}
return resolvers
}