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  }