github.com/slackhq/nebula@v1.9.0/iputil/util.go (about) 1 package iputil 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "net" 7 "net/netip" 8 ) 9 10 type VpnIp uint32 11 12 const maxIPv4StringLen = len("255.255.255.255") 13 14 func (ip VpnIp) String() string { 15 b := make([]byte, maxIPv4StringLen) 16 17 n := ubtoa(b, 0, byte(ip>>24)) 18 b[n] = '.' 19 n++ 20 21 n += ubtoa(b, n, byte(ip>>16&255)) 22 b[n] = '.' 23 n++ 24 25 n += ubtoa(b, n, byte(ip>>8&255)) 26 b[n] = '.' 27 n++ 28 29 n += ubtoa(b, n, byte(ip&255)) 30 return string(b[:n]) 31 } 32 33 func (ip VpnIp) MarshalJSON() ([]byte, error) { 34 return []byte(fmt.Sprintf("\"%s\"", ip.String())), nil 35 } 36 37 func (ip VpnIp) ToIP() net.IP { 38 nip := make(net.IP, 4) 39 binary.BigEndian.PutUint32(nip, uint32(ip)) 40 return nip 41 } 42 43 func (ip VpnIp) ToNetIpAddr() netip.Addr { 44 var nip [4]byte 45 binary.BigEndian.PutUint32(nip[:], uint32(ip)) 46 return netip.AddrFrom4(nip) 47 } 48 49 func Ip2VpnIp(ip []byte) VpnIp { 50 if len(ip) == 16 { 51 return VpnIp(binary.BigEndian.Uint32(ip[12:16])) 52 } 53 return VpnIp(binary.BigEndian.Uint32(ip)) 54 } 55 56 func ToNetIpAddr(ip net.IP) (netip.Addr, error) { 57 addr, ok := netip.AddrFromSlice(ip) 58 if !ok { 59 return netip.Addr{}, fmt.Errorf("invalid net.IP: %v", ip) 60 } 61 return addr, nil 62 } 63 64 func ToNetIpPrefix(ipNet net.IPNet) (netip.Prefix, error) { 65 addr, err := ToNetIpAddr(ipNet.IP) 66 if err != nil { 67 return netip.Prefix{}, err 68 } 69 ones, bits := ipNet.Mask.Size() 70 if ones == 0 && bits == 0 { 71 return netip.Prefix{}, fmt.Errorf("invalid net.IP: %v", ipNet) 72 } 73 return netip.PrefixFrom(addr, ones), nil 74 } 75 76 // ubtoa encodes the string form of the integer v to dst[start:] and 77 // returns the number of bytes written to dst. The caller must ensure 78 // that dst has sufficient length. 79 func ubtoa(dst []byte, start int, v byte) int { 80 if v < 10 { 81 dst[start] = v + '0' 82 return 1 83 } else if v < 100 { 84 dst[start+1] = v%10 + '0' 85 dst[start] = v/10 + '0' 86 return 2 87 } 88 89 dst[start+2] = v%10 + '0' 90 dst[start+1] = (v/10)%10 + '0' 91 dst[start] = v/100 + '0' 92 return 3 93 }