mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-15 13:41:23 +08:00
54 lines
978 B
Go
54 lines
978 B
Go
|
package nnip
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"net"
|
||
|
"net/netip"
|
||
|
)
|
||
|
|
||
|
// IpToAddr converts the net.IP to netip.Addr.
|
||
|
// If slice's length is not 4 or 16, IpToAddr returns netip.Addr{}
|
||
|
func IpToAddr(slice net.IP) netip.Addr {
|
||
|
ip := slice
|
||
|
if len(ip) != 4 {
|
||
|
if ip = slice.To4(); ip == nil {
|
||
|
ip = slice
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if addr, ok := netip.AddrFromSlice(ip); ok {
|
||
|
return addr
|
||
|
}
|
||
|
return netip.Addr{}
|
||
|
}
|
||
|
|
||
|
// UnMasked returns p's last IP address.
|
||
|
// If p is invalid, UnMasked returns netip.Addr{}
|
||
|
func UnMasked(p netip.Prefix) netip.Addr {
|
||
|
if !p.IsValid() {
|
||
|
return netip.Addr{}
|
||
|
}
|
||
|
|
||
|
buf := p.Addr().As16()
|
||
|
|
||
|
hi := binary.BigEndian.Uint64(buf[:8])
|
||
|
lo := binary.BigEndian.Uint64(buf[8:])
|
||
|
|
||
|
bits := p.Bits()
|
||
|
if bits <= 32 {
|
||
|
bits += 96
|
||
|
}
|
||
|
|
||
|
hi = hi | ^uint64(0)>>bits
|
||
|
lo = lo | ^(^uint64(0) << (128 - bits))
|
||
|
|
||
|
binary.BigEndian.PutUint64(buf[:8], hi)
|
||
|
binary.BigEndian.PutUint64(buf[8:], lo)
|
||
|
|
||
|
addr := netip.AddrFrom16(buf)
|
||
|
if p.Addr().Is4() {
|
||
|
return addr.Unmap()
|
||
|
}
|
||
|
return addr
|
||
|
}
|