github.com/kelleygo/clashcore@v1.0.2/common/nnip/netip.go (about) 1 package nnip 2 3 import ( 4 "encoding/binary" 5 "net" 6 "net/netip" 7 ) 8 9 // IpToAddr converts the net.IP to netip.Addr. 10 // If slice's length is not 4 or 16, IpToAddr returns netip.Addr{} 11 func IpToAddr(slice net.IP) netip.Addr { 12 ip := slice 13 if len(ip) != 4 { 14 if ip = slice.To4(); ip == nil { 15 ip = slice 16 } 17 } 18 19 if addr, ok := netip.AddrFromSlice(ip); ok { 20 return addr 21 } 22 return netip.Addr{} 23 } 24 25 // UnMasked returns p's last IP address. 26 // If p is invalid, UnMasked returns netip.Addr{} 27 func UnMasked(p netip.Prefix) netip.Addr { 28 if !p.IsValid() { 29 return netip.Addr{} 30 } 31 32 buf := p.Addr().As16() 33 34 hi := binary.BigEndian.Uint64(buf[:8]) 35 lo := binary.BigEndian.Uint64(buf[8:]) 36 37 bits := p.Bits() 38 if bits <= 32 { 39 bits += 96 40 } 41 42 hi = hi | ^uint64(0)>>bits 43 lo = lo | ^(^uint64(0) << (128 - bits)) 44 45 binary.BigEndian.PutUint64(buf[:8], hi) 46 binary.BigEndian.PutUint64(buf[8:], lo) 47 48 addr := netip.AddrFrom16(buf) 49 if p.Addr().Is4() { 50 return addr.Unmap() 51 } 52 return addr 53 }