netiputil.go 1.6 KB

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