utils.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Network utility functions.
  2. // Imported unchanged from Docker
  3. package libnetwork
  4. import (
  5. "errors"
  6. "fmt"
  7. "math/rand"
  8. "net"
  9. "github.com/vishvananda/netlink"
  10. )
  11. var (
  12. // ErrNetworkOverlapsWithNameservers preformatted error
  13. ErrNetworkOverlapsWithNameservers = errors.New("requested network overlaps with nameserver")
  14. // ErrNetworkOverlaps preformatted error
  15. ErrNetworkOverlaps = errors.New("requested network overlaps with existing network")
  16. // ErrNoDefaultRoute preformatted error
  17. ErrNoDefaultRoute = errors.New("no default route")
  18. networkGetRoutesFct = netlink.RouteList
  19. )
  20. // CheckNameserverOverlaps checks whether the passed network overlaps with any of the nameservers
  21. func CheckNameserverOverlaps(nameservers []string, toCheck *net.IPNet) error {
  22. if len(nameservers) > 0 {
  23. for _, ns := range nameservers {
  24. _, nsNetwork, err := net.ParseCIDR(ns)
  25. if err != nil {
  26. return err
  27. }
  28. if NetworkOverlaps(toCheck, nsNetwork) {
  29. return ErrNetworkOverlapsWithNameservers
  30. }
  31. }
  32. }
  33. return nil
  34. }
  35. // CheckRouteOverlaps checks whether the passed network overlaps with any existing routes
  36. func CheckRouteOverlaps(toCheck *net.IPNet) error {
  37. networks, err := networkGetRoutesFct(nil, netlink.FAMILY_V4)
  38. if err != nil {
  39. return err
  40. }
  41. for _, network := range networks {
  42. if network.Dst != nil && NetworkOverlaps(toCheck, network.Dst) {
  43. return ErrNetworkOverlaps
  44. }
  45. }
  46. return nil
  47. }
  48. // NetworkOverlaps detects overlap between one IPNet and another
  49. func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
  50. if len(netX.IP) == len(netY.IP) {
  51. if firstIP, _ := NetworkRange(netX); netY.Contains(firstIP) {
  52. return true
  53. }
  54. if firstIP, _ := NetworkRange(netY); netX.Contains(firstIP) {
  55. return true
  56. }
  57. }
  58. return false
  59. }
  60. // NetworkRange calculates the first and last IP addresses in an IPNet
  61. func NetworkRange(network *net.IPNet) (net.IP, net.IP) {
  62. var netIP net.IP
  63. if network.IP.To4() != nil {
  64. netIP = network.IP.To4()
  65. } else if network.IP.To16() != nil {
  66. netIP = network.IP.To16()
  67. } else {
  68. return nil, nil
  69. }
  70. lastIP := make([]byte, len(netIP), len(netIP))
  71. for i := 0; i < len(netIP); i++ {
  72. lastIP[i] = netIP[i] | ^network.Mask[i]
  73. }
  74. return netIP.Mask(network.Mask), net.IP(lastIP)
  75. }
  76. // GetIfaceAddr returns the first IPv4 address and slice of IPv6 addresses for the specified network interface
  77. func GetIfaceAddr(name string) (net.Addr, []net.Addr, error) {
  78. iface, err := net.InterfaceByName(name)
  79. if err != nil {
  80. return nil, nil, err
  81. }
  82. addrs, err := iface.Addrs()
  83. if err != nil {
  84. return nil, nil, err
  85. }
  86. var addrs4 []net.Addr
  87. var addrs6 []net.Addr
  88. for _, addr := range addrs {
  89. ip := (addr.(*net.IPNet)).IP
  90. if ip4 := ip.To4(); ip4 != nil {
  91. addrs4 = append(addrs4, addr)
  92. } else if ip6 := ip.To16(); len(ip6) == net.IPv6len {
  93. addrs6 = append(addrs6, addr)
  94. }
  95. }
  96. switch {
  97. case len(addrs4) == 0:
  98. return nil, nil, fmt.Errorf("Interface %v has no IPv4 addresses", name)
  99. case len(addrs4) > 1:
  100. fmt.Printf("Interface %v has more than 1 IPv4 address. Defaulting to using %v\n",
  101. name, (addrs4[0].(*net.IPNet)).IP)
  102. }
  103. return addrs4[0], addrs6, nil
  104. }
  105. // GenerateRandomMAC returns a random MAC address
  106. func GenerateRandomMAC() net.HardwareAddr {
  107. hw := make(net.HardwareAddr, 6)
  108. for i := 0; i < 6; i++ {
  109. hw[i] = byte(rand.Intn(255))
  110. }
  111. hw[0] &^= 0x1 // clear multicast bit
  112. hw[0] |= 0x2 // set local assignment bit (IEEE802)
  113. return hw
  114. }