github.com/moby/docker@v26.1.3+incompatible/libnetwork/internal/netiputil/netiputil.go (about)

     1  package netiputil
     2  
     3  import (
     4  	"net"
     5  	"net/netip"
     6  
     7  	"github.com/docker/docker/libnetwork/ipbits"
     8  )
     9  
    10  // ToIPNet converts p into a *net.IPNet, returning nil if p is not valid.
    11  func ToIPNet(p netip.Prefix) *net.IPNet {
    12  	if !p.IsValid() {
    13  		return nil
    14  	}
    15  	return &net.IPNet{
    16  		IP:   p.Addr().AsSlice(),
    17  		Mask: net.CIDRMask(p.Bits(), p.Addr().BitLen()),
    18  	}
    19  }
    20  
    21  // ToPrefix converts n into a netip.Prefix. If n is not a valid IPv4 or IPV6
    22  // address, ToPrefix returns netip.Prefix{}, false.
    23  func ToPrefix(n *net.IPNet) (netip.Prefix, bool) {
    24  	if ll := len(n.Mask); ll != net.IPv4len && ll != net.IPv6len {
    25  		return netip.Prefix{}, false
    26  	}
    27  
    28  	addr, ok := netip.AddrFromSlice(n.IP)
    29  	if !ok {
    30  		return netip.Prefix{}, false
    31  	}
    32  
    33  	ones, bits := n.Mask.Size()
    34  	if ones == 0 && bits == 0 {
    35  		return netip.Prefix{}, false
    36  	}
    37  
    38  	return netip.PrefixFrom(addr.Unmap(), ones), true
    39  }
    40  
    41  // HostID masks out the 'bits' most-significant bits of addr. The result is
    42  // undefined if bits > addr.BitLen().
    43  func HostID(addr netip.Addr, bits uint) uint64 {
    44  	return ipbits.Field(addr, bits, uint(addr.BitLen()))
    45  }
    46  
    47  // SubnetRange returns the amount to add to network.Addr() in order to yield the
    48  // first and last addresses in subnet, respectively.
    49  func SubnetRange(network, subnet netip.Prefix) (start, end uint64) {
    50  	start = HostID(subnet.Addr(), uint(network.Bits()))
    51  	end = start + (1 << uint64(subnet.Addr().BitLen()-subnet.Bits())) - 1
    52  	return start, end
    53  }
    54  
    55  // AddrPortFromNet converts a net.Addr into a netip.AddrPort.
    56  func AddrPortFromNet(addr net.Addr) netip.AddrPort {
    57  	if a, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok {
    58  		return a.AddrPort()
    59  	}
    60  	return netip.AddrPort{}
    61  }