resolvconf.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package bridge
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "regexp"
  6. )
  7. const (
  8. ipv4NumBlock = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
  9. ipv4Address = `(` + ipv4NumBlock + `\.){3}` + ipv4NumBlock
  10. // This is not an IPv6 address verifier as it will accept a super-set of IPv6, and also
  11. // will *not match* IPv4-Embedded IPv6 Addresses (RFC6052), but that and other variants
  12. // -- e.g. other link-local types -- either won't work in containers or are unnecessary.
  13. // For readability and sufficiency for Docker purposes this seemed more reasonable than a
  14. // 1000+ character regexp with exact and complete IPv6 validation
  15. ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})`
  16. )
  17. var nsRegexp = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
  18. func readResolvConf() ([]byte, error) {
  19. resolv, err := ioutil.ReadFile("/etc/resolv.conf")
  20. if err != nil {
  21. return nil, err
  22. }
  23. return resolv, nil
  24. }
  25. // getLines parses input into lines and strips away comments.
  26. func getLines(input []byte, commentMarker []byte) [][]byte {
  27. lines := bytes.Split(input, []byte("\n"))
  28. var output [][]byte
  29. for _, currentLine := range lines {
  30. var commentIndex = bytes.Index(currentLine, commentMarker)
  31. if commentIndex == -1 {
  32. output = append(output, currentLine)
  33. } else {
  34. output = append(output, currentLine[:commentIndex])
  35. }
  36. }
  37. return output
  38. }
  39. // GetNameserversAsCIDR returns nameservers (if any) listed in
  40. // /etc/resolv.conf as CIDR blocks (e.g., "1.2.3.4/32")
  41. // This function's output is intended for net.ParseCIDR
  42. func getNameserversAsCIDR(resolvConf []byte) []string {
  43. nameservers := []string{}
  44. for _, nameserver := range getNameservers(resolvConf) {
  45. nameservers = append(nameservers, nameserver+"/32")
  46. }
  47. return nameservers
  48. }
  49. // GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
  50. func getNameservers(resolvConf []byte) []string {
  51. nameservers := []string{}
  52. for _, line := range getLines(resolvConf, []byte("#")) {
  53. var ns = nsRegexp.FindSubmatch(line)
  54. if len(ns) > 0 {
  55. nameservers = append(nameservers, string(ns[1]))
  56. }
  57. }
  58. return nameservers
  59. }