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  }