|
@@ -0,0 +1,67 @@
|
|
|
+package bridge
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "io/ioutil"
|
|
|
+ "regexp"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ ipv4NumBlock = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
|
|
|
+ ipv4Address = `(` + ipv4NumBlock + `\.){3}` + ipv4NumBlock
|
|
|
+
|
|
|
+ // This is not an IPv6 address verifier as it will accept a super-set of IPv6, and also
|
|
|
+ // will *not match* IPv4-Embedded IPv6 Addresses (RFC6052), but that and other variants
|
|
|
+ // -- e.g. other link-local types -- either won't work in containers or are unnecessary.
|
|
|
+ // For readability and sufficiency for Docker purposes this seemed more reasonable than a
|
|
|
+ // 1000+ character regexp with exact and complete IPv6 validation
|
|
|
+ ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})`
|
|
|
+)
|
|
|
+
|
|
|
+var nsRegexp = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
|
|
|
+
|
|
|
+func readResolvConf() ([]byte, error) {
|
|
|
+ resolv, err := ioutil.ReadFile("/etc/resolv.conf")
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return resolv, nil
|
|
|
+}
|
|
|
+
|
|
|
+// getLines parses input into lines and strips away comments.
|
|
|
+func getLines(input []byte, commentMarker []byte) [][]byte {
|
|
|
+ lines := bytes.Split(input, []byte("\n"))
|
|
|
+ var output [][]byte
|
|
|
+ for _, currentLine := range lines {
|
|
|
+ var commentIndex = bytes.Index(currentLine, commentMarker)
|
|
|
+ if commentIndex == -1 {
|
|
|
+ output = append(output, currentLine)
|
|
|
+ } else {
|
|
|
+ output = append(output, currentLine[:commentIndex])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return output
|
|
|
+}
|
|
|
+
|
|
|
+// GetNameserversAsCIDR returns nameservers (if any) listed in
|
|
|
+// /etc/resolv.conf as CIDR blocks (e.g., "1.2.3.4/32")
|
|
|
+// This function's output is intended for net.ParseCIDR
|
|
|
+func getNameserversAsCIDR(resolvConf []byte) []string {
|
|
|
+ nameservers := []string{}
|
|
|
+ for _, nameserver := range getNameservers(resolvConf) {
|
|
|
+ nameservers = append(nameservers, nameserver+"/32")
|
|
|
+ }
|
|
|
+ return nameservers
|
|
|
+}
|
|
|
+
|
|
|
+// GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
|
|
|
+func getNameservers(resolvConf []byte) []string {
|
|
|
+ nameservers := []string{}
|
|
|
+ for _, line := range getLines(resolvConf, []byte("#")) {
|
|
|
+ var ns = nsRegexp.FindSubmatch(line)
|
|
|
+ if len(ns) > 0 {
|
|
|
+ nameservers = append(nameservers, string(ns[1]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nameservers
|
|
|
+}
|