github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/ipam/utils.go (about) 1 package ipam 2 3 import ( 4 "fmt" 5 "net" 6 7 "github.com/docker/docker/libnetwork/ipamapi" 8 "github.com/docker/docker/libnetwork/types" 9 ) 10 11 type ipVersion int 12 13 const ( 14 v4 = 4 15 v6 = 6 16 ) 17 18 func getAddressRange(pool string, masterNw *net.IPNet) (*AddressRange, error) { 19 ip, nw, err := net.ParseCIDR(pool) 20 if err != nil { 21 return nil, ipamapi.ErrInvalidSubPool 22 } 23 lIP, e := types.GetHostPartIP(nw.IP, masterNw.Mask) 24 if e != nil { 25 return nil, fmt.Errorf("failed to compute range's lowest ip address: %v", e) 26 } 27 bIP, e := types.GetBroadcastIP(nw.IP, nw.Mask) 28 if e != nil { 29 return nil, fmt.Errorf("failed to compute range's broadcast ip address: %v", e) 30 } 31 hIP, e := types.GetHostPartIP(bIP, masterNw.Mask) 32 if e != nil { 33 return nil, fmt.Errorf("failed to compute range's highest ip address: %v", e) 34 } 35 nw.IP = ip 36 return &AddressRange{nw, ipToUint64(types.GetMinimalIP(lIP)), ipToUint64(types.GetMinimalIP(hIP))}, nil 37 } 38 39 // It generates the ip address in the passed subnet specified by 40 // the passed host address ordinal 41 func generateAddress(ordinal uint64, network *net.IPNet) net.IP { 42 var address [16]byte 43 44 // Get network portion of IP 45 if getAddressVersion(network.IP) == v4 { 46 copy(address[:], network.IP.To4()) 47 } else { 48 copy(address[:], network.IP) 49 } 50 51 end := len(network.Mask) 52 addIntToIP(address[:end], ordinal) 53 54 return net.IP(address[:end]) 55 } 56 57 func getAddressVersion(ip net.IP) ipVersion { 58 if ip.To4() == nil { 59 return v6 60 } 61 return v4 62 } 63 64 // Adds the ordinal IP to the current array 65 // 192.168.0.0 + 53 => 192.168.0.53 66 func addIntToIP(array []byte, ordinal uint64) { 67 for i := len(array) - 1; i >= 0; i-- { 68 array[i] |= (byte)(ordinal & 0xff) 69 ordinal >>= 8 70 } 71 } 72 73 // Convert an ordinal to the respective IP address 74 func ipToUint64(ip []byte) (value uint64) { 75 cip := types.GetMinimalIP(ip) 76 for i := 0; i < len(cip); i++ { 77 j := len(cip) - 1 - i 78 value += uint64(cip[i]) << uint(j*8) 79 } 80 return value 81 }