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 }