netiputil.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. package netiputil
  2. import (
  3. "net"
  4. "net/netip"
  5. "github.com/docker/docker/libnetwork/ipbits"
  6. )
  7. func ToIPNet(p netip.Prefix) *net.IPNet {
  8. if !p.IsValid() {
  9. return nil
  10. }
  11. return &net.IPNet{
  12. IP: p.Addr().AsSlice(),
  13. Mask: net.CIDRMask(p.Bits(), p.Addr().BitLen()),
  14. }
  15. }
  16. func ToPrefix(n *net.IPNet) (netip.Prefix, bool) {
  17. if ll := len(n.Mask); ll != net.IPv4len && ll != net.IPv6len {
  18. return netip.Prefix{}, false
  19. }
  20. addr, ok := netip.AddrFromSlice(n.IP)
  21. if !ok {
  22. return netip.Prefix{}, false
  23. }
  24. ones, bits := n.Mask.Size()
  25. if ones == 0 && bits == 0 {
  26. return netip.Prefix{}, false
  27. }
  28. return netip.PrefixFrom(addr.Unmap(), ones), true
  29. }
  30. func HostID(addr netip.Addr, bits uint) uint64 {
  31. return ipbits.Field(addr, bits, uint(addr.BitLen()))
  32. }
  33. // subnetRange returns the amount to add to network.Addr() in order to yield the
  34. // first and last addresses in subnet, respectively.
  35. func SubnetRange(network, subnet netip.Prefix) (start, end uint64) {
  36. start = HostID(subnet.Addr(), uint(network.Bits()))
  37. end = start + (1 << uint64(subnet.Addr().BitLen()-subnet.Bits())) - 1
  38. return start, end
  39. }