diff --git a/nameservers_linux.go b/nameservers_linux.go index 8859ea5..1fad95b 100644 --- a/nameservers_linux.go +++ b/nameservers_linux.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "net" "os" + "strings" "github.com/Control-D-Inc/ctrld/internal/dns/resolvconffile" ) @@ -28,6 +29,7 @@ func dns4() []string { var dns []string seen := make(map[string]bool) + vis := virtualInterfaces() s := bufio.NewScanner(f) first := true for s.Scan() { @@ -39,7 +41,10 @@ func dns4() []string { if len(fields) < 2 { continue } - + // Skip virtual interfaces. + if vis.contains(string(bytes.TrimSpace(fields[0]))) { + continue + } gw := make([]byte, net.IPv4len) // Third fields is gateway. if _, err := hex.Decode(gw, fields[2]); err != nil { @@ -63,12 +68,17 @@ func dns6() []string { defer f.Close() var dns []string + vis := virtualInterfaces() s := bufio.NewScanner(f) for s.Scan() { fields := bytes.Fields(s.Bytes()) if len(fields) < 4 { continue } + // Skip virtual interfaces. + if vis.contains(string(bytes.TrimSpace(fields[len(fields)-1]))) { + continue + } gw := make([]byte, net.IPv6len) // Fifth fields is gateway. @@ -95,3 +105,26 @@ func dnsFromSystemdResolver() []string { } return ns } + +type set map[string]struct{} + +func (s *set) add(e string) { + (*s)[e] = struct{}{} +} + +func (s *set) contains(e string) bool { + _, ok := (*s)[e] + return ok +} + +// virtualInterfaces returns a set of virtual interfaces on current machine. +func virtualInterfaces() set { + s := make(set) + entries, _ := os.ReadDir("/sys/devices/virtual/net") + for _, entry := range entries { + if entry.IsDir() { + s.add(strings.TrimSpace(entry.Name())) + } + } + return s +} diff --git a/nameservers_linux_test.go b/nameservers_linux_test.go new file mode 100644 index 0000000..23f1544 --- /dev/null +++ b/nameservers_linux_test.go @@ -0,0 +1,10 @@ +package ctrld + +import ( + "testing" +) + +func Test_virtualInterfaces(t *testing.T) { + vis := virtualInterfaces() + t.Log(vis) +}